DEV Community

Cover image for I built a file transfer tool where the files never touch a server (WebRTC P2P)
Jeffrey Hamilton
Jeffrey Hamilton

Posted on

I built a file transfer tool where the files never touch a server (WebRTC P2P)

Every time you need to move a file from your phone to your computer (or vice versa), your options are:

Email it (25MB limit, uploads to a server)
Google Drive (uploads to Google's servers, stored forever)
WeTransfer (uploads to their servers, 2GB limit)
AirDrop (Apple only)
None of these are great for privacy. Your files are sitting on someone else's server.

So I built FileBeam — it transfers files directly between two devices via WebRTC. No cloud, no uploads, no size limits.

Try it: filebeam-ten.vercel.app
Source: https://github.com/JeffreyHamilton6399/filebeam

How it works
text

Device A (Sender) Device B (Receiver)
│ │
│ ── WebRTC P2P ──────────│ (files go DIRECTLY, encrypted)
│ │
└── Signaling relay ──────┘
(6-digit code + handshake only)
(NEVER sees file data)
Device A: Drop files → get a 6-digit code + QR code
Device B: Enter the 6-digit code (or scan QR)
Files transfer directly from A to B via WebRTC data channels (end-to-end encrypted via DTLS)
The signaling server only passes the 6-digit code and connection handshake — it NEVER sees the files
The architecture
Frontend: Next.js 16 + Tailwind + shadcn/ui (hosted on Vercel)
Signaling: A tiny socket.io relay (~130 lines, hosted on Render's free tier)
Transfer: WebRTC RTCPeerConnection + data channels (16KB chunks)
Encryption: WebRTC DTLS (built into the protocol — files are encrypted in transit)
Key technical decisions

  1. WebRTC data channels (not HTTP)

Files stream in 16KB chunks via RTCDataChannel. This allows true peer-to-peer transfer — the files go directly from device A to device B, never passing through any server.

  1. A minimal signaling relay

A ~130-line socket.io server relays only the 6-digit code and WebRTC SDP/ICE candidates so the two devices can find each other. It never receives, stores, or sees file data, file names, or file sizes. The room is destroyed when the transfer ends or a device disconnects.

  1. 6-digit codes = 1 million possibilities

Brute force is impractical for ephemeral rooms that auto-destroy.

  1. Stream large files

Files are read via file.stream().getReader() and sent in 16KB chunks — meaning even multi-GB files can transfer without loading into memory.

The privacy model (honest version)
Files go direct — file bytes, names, and sizes travel only over the encrypted peer-to-peer data channel. No server ever receives or stores them.
End-to-end encrypted — WebRTC DTLS encryption is built into the protocol.
No file storage anywhere — nothing is saved on any server, ever.
No accounts, no tracking, no analytics.
What the signaling server sees: the 6-digit code and connection info (IPs/ICE candidates) needed to pair the devices. That's inherent to WebRTC — two devices need to exchange connection info before they can connect directly. It never sees file data.
Open source — read every line of code.
Try it
Live: filebeam-ten.vercel.app
Source: https://github.com/JeffreyHamilton6399/filebeam

Email uploads your files. Google Drive stores them forever. FileBeam sends them directly.

FileBeam is built with Next.js 16, WebRTC, Tailwind CSS, and shadcn/ui. The signaling relay runs on Render's free tier.

Top comments (1)

Collapse
 
advantage_builder profile image
Advantage Builder

Very interesting, does it work from android to windows?