A simple proof-of-concept application for peer-to-peer video calls using PeerJS and Next.js.
See a demo at call.igorsilvestre.dev
- Real-time peer-to-peer video calls
- No server required for the actual video/audio transmission
- Simple user interface with controls for:
- Starting/ending calls
- Muting/unmuting audio
- Enabling/disabling video
- Responsive design that works on both desktop and mobile devices
This application uses PeerJS, a wrapper around WebRTC, to establish peer-to-peer connections between browsers. The key components are:
- Peer Connection: Each user gets a unique ID when they connect
- Media Streaming: Access to the user's camera and microphone using the browser's MediaDevices API
- Signaling: PeerJS handles the signaling process to establish the connection between peers
This project uses Bun as the preferred package manager. Using other package managers is not recommended to avoid potential conflicts.
First, install the dependencies:
bun install
# Alternative package managers (not recommended)
# npm install
# yarn install
# pnpm installThen, run the development server:
bun dev
# Alternative package managers (not recommended)
# npm run dev
# yarn dev
# pnpm devOpen http://localhost:3333 with your browser to see the application.
- Open the application in two different browser windows or on two different devices
- In the first window, note your ID (it's displayed in the "Your ID" field)
- In the second window, paste that ID into the "Remote ID" field
- Click "Start Call" in the second window
- Accept the browser's request to access your camera and microphone
- You should now see both video feeds and be able to communicate
- Built with Next.js 15.4.5 and React 19.1.0
- Uses PeerJS for WebRTC peer-to-peer connections
- Styled with Tailwind CSS
- Fully typed with TypeScript
- This is a proof-of-concept and not intended for production use
- No authentication or security measures are implemented
- Relies on STUN servers for NAT traversal, which may not work in all network environments
- No persistent storage of call history or user preferences
This application includes several error handling mechanisms to improve reliability:
- Media Access Fallbacks: If video+audio access fails, the app will attempt to connect with audio-only
- Connection Timeout Detection: Detects and handles cases where connections fail to establish
- Graceful Error Recovery: Provides user-friendly error messages and attempts to clean up resources properly
- Multiple STUN Servers: Uses multiple STUN servers to improve connection reliability in different network environments
- Connection Status Indicators: Visual indicators show the current connection status (connected, connecting, error, disconnected)
- Manual Reconnection: A "Retry Connection" button allows users to attempt reconnection with a new ID if the connection fails
- Enhanced Console Logging: Detailed, styled console logs help with troubleshooting connection issues
- Stable ID Generation: Uses a stable approach to ID generation to prevent issues with changing IDs
If you encounter issues with the application, here are some common problems and solutions:
- Check Connection Status: Look for the colored indicator next to "Your ID". Green means connected, yellow means connecting, red means error.
- Check Console: Press F12 to open browser developer tools and look for your ID in the console (it's highlighted in green).
- Try Refreshing: If no ID appears after waiting, try refreshing the page.
- Use Retry Button: If you see a connection error, use the "Retry Connection" button to get a new ID.
- Check Network: Ensure you have a stable internet connection.
- Browser Extensions: Some browser extensions (like Dark Reader) can interfere with WebRTC connections. Try disabling them.
- Firewall Issues: WebRTC may be blocked by firewalls in some networks. Try on a different network if possible.
- STUN Server Access: The application needs access to STUN servers. Corporate networks sometimes block these.
- Browser Support: Ensure you're using a modern browser with WebRTC support (Chrome, Firefox, Edge, Safari).
- Verify IDs: Double-check that you've entered the correct remote ID.
- Both Parties Connected: Both users need to have a green connection status before starting a call.
- Camera/Microphone Access: Ensure you've granted the browser permission to access your camera and microphone.
- Try Audio Only: If video doesn't work, the application will attempt to fall back to audio-only mode.
- Theme Issues: If you have trouble seeing text or buttons, try switching between light and dark themes using the theme toggle button in the top-right corner.
This project can be deployed using Docker and Docker Compose for easy setup and consistent environments.
-
Clone the repository:
git clone <repository-url> cd peerjs-poc
-
Build and start the container:
docker-compose up -d
-
Access the application at http://localhost:3333
-
To stop the container:
docker-compose down
The Docker setup includes:
- Multi-stage build process for optimized image size
- Production-ready configuration
- Automatic container restart
- Health checks to ensure the application is running properly
If you encounter issues with the Docker setup:
-
Build Errors: If you encounter TypeScript errors during build, the Dockerfile is configured to skip type checking. If you need to enable type checking, remove the
--no-lintflag from the build command in the Dockerfile. -
Container Not Starting: Check the container logs using:
docker compose logs
-
Port Conflicts: If port 3333 is already in use on your host machine, modify the port mapping in docker-compose.yml:
ports: - "3001:3000" # Change 3001 to any available port
- PeerJS Documentation - learn about PeerJS features and API
- WebRTC Documentation - learn about the underlying WebRTC technology
- Next.js Documentation - learn about Next.js features and API
- Docker Documentation - learn about Docker