WebDrop is a web-based AirDrop-style MVP for nearby browser-to-browser file transfer.
Users open the same website, confirm a device name, automatically discover nearby devices, send a transfer request, and move file bytes directly between browsers over WebRTC RTCDataChannel.
- The frontend connects to the Socket.IO signaling server.
- The server places the socket into an internal nearby discovery channel derived from the client IP.
- The client receives only nearby
PublicPeerobjects. - A sender chooses a nearby device and sends a transfer request.
- The receiver accepts or rejects the request.
- On accept, the browsers exchange WebRTC offer, answer, and ICE candidates through the signaling server.
- File metadata and chunks are sent over
RTCDataChannel. - The receiver rebuilds the file as a
Bloband shows a download link.
The server never receives, stores, or relays file contents.
- pnpm workspaces
- Turbo
- TypeScript
- Next.js App Router
- React
- Tailwind CSS
- Zustand
- Node.js, Express, Socket.IO
- WebRTC
RTCDataChannel - Shared package for events, constants, and common types
Install pnpm if needed:
corepack enable
corepack prepare [email protected] --activateInstall dependencies:
pnpm installFrontend, apps/web/.env.local:
NEXT_PUBLIC_SIGNALING_SERVER_URL=http://localhost:4000Server, apps/server/.env:
PORT=4000
CLIENT_ORIGIN=http://localhost:3000Example files are included in both apps.
pnpm devThen open:
- Frontend:
http://localhost:3000 - Signaling health check:
http://localhost:4000/health
Open two browser windows to test nearby discovery and transfers.
The monorepo has three main parts:
apps/web: the Next.js UI, Socket.IO client, WebRTC connection logic, and file chunking.apps/server: the Express and Socket.IO signaling server.packages/shared: shared socket event names, constants, and TypeScript contracts.
The server is intentionally small. It tracks connected peers in memory, groups them for nearby discovery, forwards transfer requests, and forwards WebRTC signaling messages. It does not include authentication, storage, database access, accounts, or file history.
The MVP groups nearby users by client IP. In production this usually means users behind the same NAT or network egress can see each other. This is a practical MVP strategy, but it is not precise physical proximity.
Limitations:
- Different networks in the same location may not see each other.
- Carrier-grade NAT can group unrelated users.
- VPNs and privacy relays can change discovery behavior.
- Local development uses a normalized local-development group for loopback and private LAN addresses.
- TURN server support for stricter networks
- Better nearby detection
- QR pairing fallback
- Optional device verification
- PWA install
- End-to-end encryption layer
- Redis adapter for multi-instance scaling