How Peer-to-Peer File Transfer Works in the Browser
“Peer-to-peer” means two devices talk to each other directly instead of through a central server. For file sharing, that is attractive: no storage costs, no upload step, no copy left behind. Browsers have supported it since WebRTC arrived in the 2010s, but getting two arbitrary devices on the internet to connect directly takes a few clever steps. This guide walks through them, using BeamDrop as the running example.
The cast
- Two peers: the sender’s browser and the recipient’s browser.
- A signaling server: a small server that introduces the peers. For BeamDrop, a Node.js service on wetransfertool.com.
- STUN servers: public helpers that tell a browser its own public address. BeamDrop uses Google’s and Cloudflare’s.
- Optionally, a TURN server: a relay of last resort. BeamDrop deliberately has none.
Step 1: Signaling — exchanging business cards
Two browsers can’t connect until they know how to reach each other, and they can’t exchange that information without a channel. Signaling solves the chicken-and-egg problem: both browsers connect to a server they can reach — here over a WebSocket — and pass small messages through it.
WebRTC itself doesn’t define the signaling format; each app picks its own. The content, however, is standard:
- An offer and an answer in SDP (Session Description Protocol): which kind of channel to open and the fingerprint of each side’s encryption certificate.
- ICE candidates: possible network addresses and ports where each browser might be reachable.
On BeamDrop, the server checks that every message has exactly this shape, refuses anything binary, and caps how much a single connection can pass along — so it physically can’t be used to move files. The file list itself only travels later, over the encrypted peer connection.
Step 2: Finding a path through NAT
Most devices don’t have a public IP address of their own. Your laptop has a private address like 192.168.1.23, and your router performs NAT (network address translation), sharing one public address among all your devices. Nothing on the internet can reach 192.168.1.23 directly.
WebRTC’s answer is ICE (Interactive Connectivity Establishment). Each browser gathers candidates:
- Host candidates: its local addresses. If both devices are on the same Wi-Fi, these usually work right away.
- Server-reflexive candidates: its public address and port as seen from outside, learned by asking a STUN server “what address am I coming from?”.
- Relay candidates: an address on a TURN relay, if the app configures one.
Both sides then try pairs of candidates simultaneously. Sending packets outward opens short-lived “holes” in each router’s NAT, letting the other side’s packets in — a technique called hole punching. The first pair that works wins.
Step 3: When hole punching fails
Some networks make direct connections impossible: strict corporate firewalls that block UDP, “symmetric” NATs that change the public port for every destination, carrier-grade NAT on some mobile networks, or guest Wi-Fi that isolates clients.
The standard fix is TURN: a server in the middle that relays every packet. It works almost everywhere — but it means all your data flows through someone else’s machine. It is encrypted end to end, but the relay operator still carries every byte and pays for the bandwidth.
BeamDrop chooses not to run a TURN relay. If no direct path is found within about 30 seconds, it shows a message suggesting the usual fixes: same Wi-Fi, a mobile hotspot on one side, or a different browser. In practice most home and mobile connections can connect directly.
Step 4: Encryption with DTLS
Once a path is found, the browsers perform a DTLS handshake — TLS, the protocol behind HTTPS, adapted for UDP. Each side checks that the other’s certificate matches the fingerprint it received in the SDP during signaling.
This leaves one theoretical weakness: whoever controls signaling could swap the fingerprints and sit in the middle. That’s why BeamDrop shows a security check — five emoji computed from both fingerprints. If the symbols match on both screens, the connection is genuinely between your two browsers.
Step 5: Moving the bytes
On top of DTLS runs SCTP, which gives WebRTC its data channels: ordered, reliable message streams, like a WebSocket between two browsers. A file transfer app then does three jobs:
- Chunking. Files are read in pieces (BeamDrop uses 64–256 KB, depending on what the other browser accepts) and sent as individual messages.
- Backpressure. The sender watches how much data is waiting in the channel’s buffer (
bufferedAmount) and pauses when it’s full; BeamDrop also waits for the recipient to confirm what it has written to disk, so a slow disk never causes memory to balloon. - Integrity. The sender computes a SHA-256 hash while reading the file; the recipient hashes what it receives and compares the two.
Step 6: Saving on the other side
Receiving is as tricky as sending, because a web page can’t simply write to your disk. Depending on the browser, BeamDrop uses the File System Access API (Chrome, Edge), a service worker that turns the incoming stream into a normal download (Firefox, Chrome on Android), or temporary origin-private storage (Safari). Each approach avoids holding the whole file in memory.
Peer-to-peer vs upload services at a glance
| Peer-to-peer | Upload, then download | |
|---|---|---|
| Both online at the same time | Required | Not required |
| Upload wait | None | Full file |
| Size limits | Recipient’s disk | Provider’s plan |
| Copies on servers | None | At least one, for days or weeks |
| Works on every network | Most; some block it | Yes |
Peer-to-peer isn’t a replacement for every use of cloud storage, but for “send this to that person right now”, it is simpler and more private. Ready to try it? Send a file with BeamDrop, or read Security & privacy for what our server can see.
Frequently asked questions
Is WebRTC file transfer encrypted?
Yes. WebRTC data channels are always encrypted with DTLS; browsers do not offer an unencrypted mode.
What is a STUN server?
A STUN server tells your browser what public IP address and port it appears to have from the internet, so it can share that with the other peer. It never carries the actual data.
What is a TURN server and why doesn't BeamDrop use one?
A TURN server relays all traffic between peers when a direct connection is impossible. That would put every file byte on our servers, which BeamDrop is designed to avoid.