PING is a secure and feature-rich chat application offering end-to-end encrypted (E2EE) private messaging, video calls, voice calls, and group chats. Built with Next.js for both the frontend and backend, it ensures a seamless and modern user experience. Real-time communication is powered by an Express-based socket server, delivering fast and reliable messaging.
- 💬 Real-time messaging with other users
- 🔒 End-to-end encrypted (E2EE) private messaging
- 🔍 Advanced search functionality for finding users easily
- 🎨 Customizable themes
- 📱 Fully responsive design, accessible on any device
- 😍 Group chat support
- 🤖 Privacy settings for user control
- 👤 User profile management
- 🔐 Secure authentication and authorization system
NEXT_PUBLIC_BACKEND_URL=your_backend_urlNEXT_PUBLIC_UPLOADTHING_SECRET=your_secret_keyNEXT_PUBLIC_UPLOADTHING_APP_ID=your_app_idNEXT_PUBLIC_JWT_SECRET=your_jwt_secret
DATABASE_URL=your_database_urlPORT=your_backend_portJWT_SECRET=your_jwt_secret
Navigate to both frontend and backend folders and run:
- Gets media stream (
getUserMedia) - Notifies User 2 via WebSocket (
webrtc:incoming-call) - Does NOT create an offer yet (Waits for User 2 to accept)
- Initializes
RTCPeerConnection - Creates an offer (
createOffer()) - Sets local description (
setLocalDescription(offer)) - Sends SDP offer to User 1 via WebSocket (
webrtc:offer)
- Initializes
RTCPeerConnection - Sets remote description (
setRemoteDescription(offer)) - Creates an answer (
createAnswer()) - Sets local description (
setLocalDescription(answer)) - Sends SDP answer to User 2 via WebSocket (
webrtc:answer)
- Sets remote description (
setRemoteDescription(answer)) - 🎯 Once set, both peers should see each other's video
- Both peers send their ICE candidates via WebSocket (
webrtc:candidate) - Each peer receives and adds the ICE candidate (
addIceCandidate())
If you find PING helpful, please consider starring ⭐ the repository. Your support helps us grow and improve this project!

