The short version: your file goes straight from one browser to another over a
WebRTC data channel. It is never uploaded to or stored on any server we run.
Finding the other peer (signaling)
Two browsers behind NAT can't address each other directly. This app uses public
WebTorrent WebSocket trackers (the BitTorrent tracker protocol) for the introduction.
Both announce the same infohash (from app ID + your room) and the tracker relays
each side's WebRTC handshake, the SDP offer/answer. It passes only these tiny text
messages and never sees your files.
Punching through NAT (STUN + ICE)
Each browser asks a STUN server "what's my public IP:port?" and collects candidate
addresses. The browser's built-in ICE agent then tries every candidate pair and keeps
the first that connects. On the same network this is a direct peer-to-peer link that touches
no server at all.
When direct fails (TURN relay)
Strict/corporate firewalls (symmetric NAT) block direct connections. ICE then falls back to a
TURN relay: both peers send to a relay that forwards between them. This app uses
metered.ca (the
OpenRelay project). Free tier caps relayed traffic at ~20 GB/month, and TURN relays
every byte, so a transfer counts roughly twice (in + out). Direct transfers skip it entirely.
For the nerds
- Encryption: WebRTC data channels are always DTLS-encrypted end-to-end. Even
when relayed, TURN only sees ciphertext. SDP fingerprints let each peer verify the other.
- Topology: full mesh. With N peers, the sender uploads N−1 copies of a file. Fine
for a few peers, heavy beyond ~8.
- Rendezvous: the room ID lives in the URL
#hash, so the static host
(GitHub Pages) needs no server-side routing.
- Diagnostics: the box below shows the real chosen candidate pair (RELAY vs DIRECT) with actual
IPs and the STUN/TURN endpoint used. "inspect connections" re-reads WebRTC's own stats.
- Limits: 5 MB per file, received files buffered in memory, no resume if a tab closes
mid-transfer.