WebRTC Video Call App
A minimal but production-ready React + Node.js WebRTC video call application that enables two laptops on different networks to stream live video/audio to each other using peer-to-peer connections.
🎯 Features
- P2P Video/Audio Streaming: Media never touches the backend server
- Cross-Network Support: Works between different networks using ngrok tunneling
- Real-time Signaling: WebSocket-based signaling server for WebRTC negotiation
- Modern UI: Built with React, TypeScript, and Tailwind CSS
- STUN Support: Uses Google's free STUN servers for NAT traversal
🧩 Tech Stack
Frontend
- React 18 + Vite
- TypeScript
- Tailwind CSS
- Native WebRTC APIs
Backend
- Node.js + Express
- WebSocket (ws library)
- In-memory room management
🚀 Quick Start
Prerequisites
- Node.js 18+ and npm
- ngrok (for cross-network calls)
- Two devices with cameras and microphones
Installation
- Clone and install dependencies:
# Install backend dependencies
cd server
npm install
# Install frontend dependencies
cd ../client
npm install
Running the Application
Step 1: Start the Signaling Server
cd server
npm run dev
The server will start on http://localhost:8080 with:
- Health check:
http://localhost:8080/healthz - WebSocket endpoint:
ws://localhost:8080/ws
Step 2: Expose Server with ngrok (for cross-network calls)
In a new terminal:
ngrok http 8080
Copy the WSS URL (e.g., wss://abc123.ngrok.io/ws) - you'll need this for the frontend.
Note: For local testing on the same network, you can use
ws://localhost:8080/wsdirectly.
Step 3: Start the Frontend
In a new terminal:
cd client
npm run dev
The frontend will start on http://localhost:3000
Using the App
On Laptop 1:
- Open
http://localhost:3000 - Enter the ngrok WSS URL (e.g.,
wss://abc123.ngrok.io/ws) - Enter a room ID (e.g.,
room-123) - Click "Join Room"
- Allow camera/microphone permissions
- Open
On Laptop 2:
- Open
http://localhost:3000(or the ngrok URL if using HTTPS) - Enter the same ngrok WSS URL
- Enter the same room ID
- Click "Join Room"
- Allow camera/microphone permissions
- Open
Video Call:
- Both users should see each other's video/audio streams
- The connection is peer-to-peer (media doesn't go through the server)
📁 Project Structure
Gestr/
├── server/ # Backend signaling server
│ ├── index.js # Express + WebSocket server
│ └── package.json
├── client/ # Frontend React app
│ ├── src/
│ │ ├── components/ # React components
│ │ │ ├── RoomJoin.tsx
│ │ │ └── VideoCall.tsx
│ │ ├── hooks/ # Custom hooks
│ │ │ └── useWebRTC.ts
│ │ ├── App.tsx
│ │ └── main.tsx
│ └── package.json
└── README.md
🔧 Configuration
Backend
- Port: Default
8080(set viaPORTenvironment variable) - WebSocket Path:
/ws - Health Check:
/healthz
Frontend
- Port: Default
3000(configured invite.config.ts) - Signaling URL: Entered by user in the UI
WebRTC
- STUN Servers: Google's free STUN servers
stun:stun.l.google.com:19302stun:stun1.l.google.com:19302
- TURN: Not included (can be added later for restrictive NATs)
🌐 Network Requirements
- HTTPS/WSS: Required for camera/microphone access in browsers
- ngrok: Provides HTTPS/WSS tunnel for cross-network calls
- Firewall: Ensure WebRTC ports are not blocked (typically UDP 1024-65535)
🐛 Troubleshooting
Camera/Microphone Not Working
- Ensure you're using HTTPS/WSS (not HTTP/WS)
- Check browser permissions
- Try a different browser (Chrome/Firefox recommended)
Connection Fails
- Verify ngrok is running and URL is correct
- Check that both users are using the same signaling URL and room ID
- Check browser console for errors
- Ensure firewall allows WebRTC traffic
No Video/Audio
- Check that both peers have joined the same room
- Verify STUN servers are accessible
- For restrictive NATs, consider adding TURN servers
📝 Development
Backend Scripts
npm run dev- Start with nodemon (auto-reload)npm start- Start production server
Frontend Scripts
npm run dev- Start development servernpm run build- Build for productionnpm run preview- Preview production build
🔒 Security Notes
- This is a minimal implementation for demonstration
- In production, consider:
- Authentication/authorization
- Rate limiting
- Input validation
- TURN server for restrictive networks
- HTTPS certificates
📄 License
MIT
Log in or sign up for Devpost to join the conversation.