Welcome to FullStack. We use cookies to enable better features on our website. Cookies help us tailor content to your interests and locations and provide other benefits on the site. For more information, please see our Cookies Policy and Privacy Policy.
Creating a Simple File-Transfer WebRTC React Web Application
Written by
Victor Gonzalez
Last updated on:
October 1, 2025
Written by
Last updated on:
October 1, 2025
In this post, you will learn how to use the WebRTC API methods to transfer data peer-to-peer.
WebRTC is an open-source project that allows web applications to transfer data peer-to-peer. In this post, you will learn how to use the WebRTC API methods to transfer data peer-to-peer.
Communication between web applications is possible with WebRTC. You can use an API to create a peer-to-peer connection between two clients and share data. To achieve a connection between a local client and a remote client, you will use the JavaScript interface RTCPeerConnection, as you can see in the image below named Code Reference #1.
Create a connection using WebRTC
To create a connection between a local peer and a remote, you can use The RTCPeerConnection interface. It provides methods to connect, maintain, and monitor the connection and close the connection to a remote peer.
One of the main options to create a connection is the iceServers. The URL’s property specifies the URL of the server to be used for ICE negotiations. These STUN servers are used to discover between each peer its public IP and port, and then pass the public IP on to another peer. The TURN servers are used to relay traffic if the connection peer-to-peer fails
This post assumes that you have a WeRTC connection between clients and it will focus on the way to send data. A WebRTC will be called peerConnection. For this, WebRTC has the option to create a network channel between the clients when it has established the connection. According to the above, it should use the RTCDataChannel JavaScript. Code Reference #2 shows an example.
Create channel
You can create a network channel between the peers when the connection between the peers is established.
According to Code Reference #2, each peerConnection will create a channel by calling the method createDataChannel and you will need to set the binaryType property as arraybuffer. On the other side, it must implement the ondatachannel event handler to process the data sent as you can see in the next Code Reference #3.
const onDataChannelCallback = (event) => {
const { channel } = event;
let receivedBuffer = [];
let totalBytesFileBuffer = 0;
let totalBytesArrayBuffers = 0;
channel.onmessage = (event) => {
const { data } = event;
[...]
};
};
Code Reference #3
The file transfer has a problem when it needs to send a big file because the browser has by default a maximum buffer of 256kB.
Transfer data by chunks
One solution for the bigger files is to send small messages through the channel. Therefore, you will use the method arrayBuffer to split the file into an array buffer and it will send a flag to say that it has sent the last file chunk. The file chunks will have a size of 64kB. It also will send the arrayBufferbyteLength through the channel (see code reference #4). Furthermore, it is important to know that all the chunks MUST arrive and in the right order to get the file correctly.
transferFile(fileToShare) {
this.#channel.onopen = async () => {
const arrayBuffer = await fileToShare.arrayBuffer();
try {
this.send(
JSON.stringify({
totalByte: arrayBuffer.byteLength,
dataSize: Channel.MAXIMUM_SIZE_DATA_TO_SEND,
})
);
for (
let index = 0;
index < arrayBuffer.byteLength;
index += Channel.MAXIMUM_SIZE_DATA_TO_SEND
) {
this.send(
arrayBuffer.slice(index, index + Channel.MAXIMUM_SIZE_DATA_TO_SEND)
);
}
this.send(Channel.LAST_DATA_OF_FILE);
} catch (error) {
console.error("error sending big file", error);
}
};
returntrue;
}
Code Reference #5
Furthermore, it is important to know that the chunks are sequentially sending and if it will overflow the outgoing channel buffer. So, you will add all chunks to a queue to pop and send each one when the channel buffer is below the threshold specified. To know if the channel buffer is below the threshold, you will use the bufferedamountlow event. In the code reference #6 below, you can see the queue handler and send handler.
The side where it will receive all file chunks will set an array to store the chunks or array buffers. The stop method to know if it has received all file chunks is when the channel gets a Channel.LAST_DATA_OF_FILE value-like message. The next step is to download the file and the final step is to close the channel (see Code Reference #7).
Finally, you will set all chunks into a new array buffer and put the new array buffer into a Blob after it downloads, as you can see in the Code Reference #8.
The application to test the above example is divided into two projects: UI and Server and I’ve created a small demo on YouTube to show you how it works.
What is WebRTC, and why use it for file transfers?
WebRTC is an open-source technology that enables real-time, peer-to-peer communication between browsers and applications. Using WebRTC for file transfers eliminates the need for a central server, allowing users to send files directly to each other for faster and more secure data exchange.
How does WebRTC establish a peer-to-peer connection?
WebRTC uses the RTCPeerConnection interface to create and manage a peer-to-peer connection between clients. It relies on STUN servers to discover each peer’s public IP and TURN servers when direct peer-to-peer connections fail, ensuring a reliable connection path.
How are files transferred between peers?
Files are sent using RTCDataChannel, a feature of WebRTC that creates a dedicated communication channel between peers. Since browsers limit buffer sizes, large files are split into 64kB chunks and sent sequentially. A special flag indicates the final chunk so the receiving client can reassemble the file correctly.
How does the application handle buffer limits and performance issues?
The app uses a queue system to manage outgoing chunks and prevents exceeding the browser’s default buffer threshold of 256kB. When the buffer reaches its limit, the app pauses sending and resumes once the channel’s buffered amount drops, ensuring smooth and reliable transfers without data loss.
How are received file chunks reconstructed on the receiving side?
The receiving peer stores incoming chunks in memory until the final chunk indicator is received. The chunks are then combined into a single ArrayBuffer, converted into a Blob, and downloaded as a complete file. This ensures the original file structure is preserved.
AI is changing software development.
The Engineer's AI-Enabled Development Handbook is your guide to incorporating AI into development processes for smoother, faster, and smarter development.
Enjoyed the article? Get new content delivered to your inbox.
Subscribe below and stay updated with the latest developer guides and industry insights.
Thank you! Your submission has been received!
Oops! Something went wrong while submitting the form.