MeetX : Real-Time Video Calling App

November 13, 2024

What Is This?

meetX is a real-time peer-to-peer video calling web application, similar to Google Meet, built entirely from scratch. Users can sign up, create or join rooms, and have multi-participant video calls — all powered by browser-native WebRTC with a custom Socket.IO signalling server.

Tech Stack

Frontend: Remix v2, React 18, TypeScript, Tailwind CSS, Shadcn UI, WebRTC, Socket.IO Client

Backend: Express.js, Socket.IO, Redis, JWT (HTTP-only cookies)

DevOps: GitHub Actions CI/CD, deployed on Render

How It Works

Multi-Peer Mesh Architecture

Every participant connects directly to every other participant via WebRTC , no central media server needed. The server acts purely as a signalling relay, forwarding SDP offers/answers and ICE candidates between peers. All audio and video flows peer-to-peer.

Room & Call Flow

  1. User creates or joins a room with a room ID
  2. Server notifies existing peers about the new user and sends back the current peer list
  3. For each existing peer, the new user creates an RTCPeerConnection, generates an SDP offer, and sends it via the signalling server
  4. Existing peers respond with SDP answers completing the WebRTC handshake
  5. ICE candidates are exchanged for NAT traversal using Google's public STUN servers
  6. P2P video streams are established each remote track is rendered in a dynamically created <video> element

Signalling Server

The Socket.IO server handles four core events — join-room, offer, answer, and ice-candidate. It maintains a server-side peers Map tracking connected users and their socket IDs. The server never processes media — it only relays signalling messages.

Authentication

Custom-built auth using Redis as the user store. Passwords are hashed, JWTs are signed and stored as HTTP-only cookies. Socket.IO connections are authenticated via middleware that parses the cookie from the WebSocket handshake and verifies the JWT.

Key Engineering Decisions

  • Mesh topology — every peer connects to every other peer directly, avoiding the complexity of an SFU/MCU media server while keeping latency low for small rooms
  • Module-level Maps for peer connections and video refs — stable references across React renders, avoiding stale closures in async WebRTC callbacks
  • Singleton socket pattern — a single Socket.IO connection reused across the entire app
  • Remix loaders/actions for server-side auth checks and redirects, cleanly separating concerns from client-side WebRTC logic
  • Redis hashes as a lightweight user store — no schema migrations, no ORM overhead

What I Learned

Building meetX gave me deep hands-on experience with WebRTC internals — SDP negotiation, ICE candidate exchange, STUN/NAT traversal, and managing multiple peer connections simultaneously. It also reinforced my understanding of real-time signalling architectures and the challenges of coordinating state between server-side socket rooms and client-side peer connection maps.

View the source code →