PeerJS
PeerJS wraps the browser’s nativeRTCPeerConnection and RTCDataChannel APIs to provide a simpler connection model. It handles:
- Signaling: exchanging SDP offers/answers between peers through the PeerJS cloud or a self-hosted
peerjs-server - ICE negotiation: gathering and exchanging ICE candidates so peers can find a route to each other
- Data channels: opening a reliable binary channel once the connection is established
Peer instance with a Warp Code-derived ID (e.g., sr-warp-cosmic-falcon) and connects to a remote peer using the receiver’s matching ID. The DataConnection object returned by PeerJS is stored in Zustand’s useWarpStore and used for all file chunk transmission.
ICE negotiation
ICE (Interactive Connectivity Establishment) is the protocol WebRTC uses to discover the best network path between two peers. HashDrop configures ICE servers insrc/lib/webrtc-ice.ts.
Default ICE servers
Dynamic ICE server fetch with fallback
At runtime,getIceServers() attempts to load fresh credentials from the /api/webrtc/ice-servers endpoint (which can be backed by a Metered TURN subscription for production-grade relay capacity). If the API is unavailable or returns an error, the function falls back transparently to DEFAULT_ICE_SERVERS.
Data channel and chunked transfer
Once the WebRTC peer connection is established, PeerJS opens a reliable binary data channel. HashDrop splits the file into 16 KB chunks (ArrayBuffer slices), assigns each chunk a sequence number, and sends them in order. The receiver buffers incoming chunks and reconstructs the file once all chunks have arrived.
Key properties of the data channel transfer:
- Chunk size: 16,384 bytes (16 KB)
- Transfer type: binary (
ArrayBuffer) - Sequencing: each chunk carries an index; the receiver tracks received indices and rejects duplicates
- Integrity: the sender computes a SHA-256 hash before sending; the receiver recomputes and compares after reassembly
Transport policy
'all' tells WebRTC to try every candidate type — host (LAN), server-reflexive (STUN), and relayed (TURN) — in priority order. This maximises the chance of a direct connection while keeping relay as an automatic fallback.
When no direct or STUN-assisted path can be established, WebRTC falls back to the TURN relay servers included in the ICE server list. If relay via TURN is also unavailable, HashDrop can fall back to its own server-side relay mode. See Relay mode for details.
DTLS (Datagram Transport Layer Security) and SRTP (Secure Real-time Transport Protocol) encryption are mandatory in all WebRTC implementations. Every byte transmitted over a HashDrop data channel is encrypted end-to-end with no additional configuration required.