A secure, peer-to-peer chat and file sharing application built with WebRTC, React, and end-to-end encryption. No servers store your messages or files - everything is transmitted directly between peers.
- True P2P Communication: Direct peer-to-peer data transfer with zero server intermediation after connection establishment
- Custom Signaling Infrastructure: Built dedicated PeerJS signaling server for WebRTC negotiation and peer coordination
- Distributed Room Management: Decentralized room system with peer discovery and automatic connection orchestration
- Multi-Server Orchestration: Coordinated deployment across room management, signaling, and TURN relay infrastructure
- NAT Traversal Implementation: Full STUN/TURN server integration with ICE candidate negotiation for symmetric NAT penetration
- Dynamic TURN Credential Management: Real-time Twilio TURN server credential fetching with automatic failover to STUN
- ICE Connection State Machine: Robust connection lifecycle management with automatic reconnection and state recovery
- Multi-Network Connectivity: Reliable connections across corporate firewalls, mobile networks, and symmetric NATs
- Chunked Transfer Protocol: Custom file chunking algorithm with configurable chunk sizes (16KB) for large file streaming
- Parallel Multi-Peer Broadcasting: Efficient file distribution to multiple peers with concurrent chunk transmission
- Reliability Layer: Built on top of WebRTC DataChannels with ordered, reliable delivery guarantees
- Binary Data Handling: Raw ArrayBuffer manipulation with optimized memory management for large payloads
- End-to-End AES-GCM Encryption: 256-bit encryption using Web Crypto API with per-peer key generation
- Zero-Knowledge Architecture: No server-side message or file storage - cryptographic operations occur client-side only
- Key Exchange Protocol: Automated key distribution over established WebRTC connections
- Perfect Forward Secrecy: Ephemeral session keys that never leave the browser memory
- Node.js/Express: Custom signaling server and room management API
- PeerJS Server: WebRTC signaling with custom path configuration and connection tracking
- Twilio Network Traversal API: Dynamic TURN server credential generation
- Real-time Notifications: Push-based peer discovery system with 1s polling intervals
- WebRTC DataChannels: Low-latency, bidirectional peer-to-peer data streaming
- ICE (Interactive Connectivity Establishment): Full implementation with candidate gathering and connectivity checks
- STUN/TURN Protocols: Google STUN servers + Twilio TURN relays for universal connectivity
- SDP Negotiation: Offer/answer exchange with ICE candidate trickle
- React 18 + TypeScript: Type-safe component architecture
- Custom WebRTC Hook: Encapsulated P2P connection management with lifecycle handling
- Web Crypto API: Native browser cryptography for AES-GCM encryption
- QR Code Generation: Room link encoding for cross-device sharing
- Multi-Service Architecture: Separate deployments for frontend, room server, and signaling server
- Cold Start Optimization: Health check polling with automatic retry logic for serverless deployments
- CORS Configuration: Cross-origin request handling for distributed service communication
- Node.js 18+ and npm/yarn/pnpm
- A room signaling server (see Server Setup below)
- Clone the repository:
git clone <repository-url>
cd p2p-chat- Install dependencies:
npm install- Create a
.envfile:
VITE_ROOM_SERVER_URL=http://localhost:3001- Start the development server:
npm run dev- Open your browser to
http://localhost:5173
The application requires two backend services:
Handles room creation, peer discovery, and TURN credential management.
Repository: p2p-file-sharing-backend
Features:
- Room creation and peer coordination
- Twilio TURN server integration
- Peer notification system
- Health checks for cold start detection
Set the backend URL in your .env file:
VITE_ROOM_SERVER_URL=https://your-backend-url.comHandles WebRTC signaling and peer-to-peer connection establishment.
Repository: p2p-signaling-server
Features:
- WebRTC signaling coordination
- Peer connection/disconnection tracking
- Health check endpoint
- CORS enabled for cross-origin requests
Quick Setup:
const express = require('express');
const { ExpressPeerServer } = require('peer');
const cors = require('cors');
const http = require('http');
const app = express();
const server = http.createServer(app);
app.use(cors());
// Health check endpoints
app.get('/', (req, res) => {
res.json({
status: 'ok',
service: 'PeerJS Signaling Server',
uptime: process.uptime()
});
});
app.get('/health', (req, res) => {
res.json({ status: 'ok', uptime: process.uptime() });
});
// PeerJS server configuration
const peerServer = ExpressPeerServer(server, {
path: '/',
debug: true,
allow_discovery: true
});
app.use('/peerjs', peerServer);
peerServer.on('connection', (client) => {
console.log(`π Peer connected: ${client.getId()}`);
});
peerServer.on('disconnect', (client) => {
console.log(`β Peer disconnected: ${client.getId()}`);
});
const PORT = process.env.PORT || 9000;
server.listen(PORT, () => {
console.log(`π PeerJS Signaling Server on port ${PORT}`);
console.log(`π‘ Endpoint: /peerjs`);
});Deployment: Deploy to any Node.js hosting service (Render, Heroku, Railway, etc.)
- Click "Connect" to initialize your peer connection
- Navigate to the "Room" tab
- Click "Create New Room"
- Share the generated room code or QR code with others
- Click "Connect" to initialize your peer connection
- Navigate to the "Room" tab
- Enter a room code and click "Join Room"
- Or scan a QR code and open the link
- Join a room with at least one other peer
- Navigate to the "Chat" tab
- Type your message and press Enter or click Send
- Messages are automatically encrypted before sending
- Join a room with at least one other peer
- Navigate to the "Files" tab
- Click "Choose File" or drag and drop files
- Files are encrypted and sent in chunks to all connected peers
- AES-GCM 256-bit Encryption: Authenticated encryption with associated data (AEAD) for message integrity
- Per-Peer Key Derivation: Unique cryptographic keys generated for each peer connection using Web Crypto API
- Key Exchange Protocol: Secure key transmission over already-established encrypted WebRTC channels
- Zero-Knowledge Server Design: No plaintext data ever touches server infrastructure - all encryption happens client-side
- Memory-Only Key Storage: Cryptographic material stored in browser memory only, never persisted to disk
- Man-in-the-Middle Prevention: End-to-end encryption ensures signaling servers cannot decrypt payload
- Perfect Forward Secrecy: Ephemeral session keys provide protection even if future keys are compromised
- Replay Attack Protection: GCM mode provides authentication tags for message integrity verification
- Full ICE Protocol: Implements Interactive Connectivity Establishment (RFC 8445)
- Candidate Gathering: Collects host, server reflexive (srflx), and relay candidates
- Connectivity Checks: Automated STUN binding checks across all candidate pairs
- Aggressive Nomination: Optimized candidate selection for fastest path establishment
- Multi-Provider Setup: Google STUN servers for NAT discovery + Twilio TURN for relay
- Dynamic Credential Rotation: On-demand TURN credential fetching from Twilio Network Traversal API
- Fallback Strategies: Graceful degradation from direct β STUN β TURN relay paths
- IPv4/IPv6 Support: Dual-stack ICE candidate generation with configurable priority
- β Direct P2P: ~30% (same local network or no NAT)
- β STUN-assisted: ~60% (port-restricted NAT, address-restricted NAT)
- β TURN relay: ~95%+ (symmetric NAT, corporate firewalls, mobile carriers)
- π― Combined: 99%+ connectivity across all network topologies
src/
βββ components/ # React components
β βββ Header.tsx
β βββ ChatPanel.tsx
β βββ FilePanel.tsx
β βββ RoomPanel.tsx
β βββ TabBar.tsx
βββ hooks/
β βββ useWebRTC.ts # WebRTC connection logic
βββ utils/
β βββ crypto.ts # Encryption utilities
βββ types/
β βββ index.ts # TypeScript types
βββ App.tsx # Main app component
- Browser Support: Requires modern browsers with WebRTC and Web Crypto API support
- File Size: Very large files (>100MB) may cause performance issues
- Connection Limits: Optimal performance with 2-10 peers per room
- Mobile Safari: May have limitations with background tab connections
Contributions are welcome! Please feel free to submit a Pull Request.
MIT License - feel free to use this project for personal or commercial purposes.
Built by Martin Wong
- PeerJS for simplifying WebRTC
- Open Relay Project for free TURN servers
- The WebRTC community for documentation and examples