~/sabarish.dev
← all posts

~/posts/video-conferencing-app

Video Conferencing App: Agora RTC, screen sharing, and live chat

Sabarish R2 min read
  • full-stack
  • react
  • realtime
  • webrtc

Video conferencing is the hardest "standard" full-stack feature to build from scratch, because the real-time layer splits into two very different jobs: the media plane (video and audio packets that need low latency and don't survive a chat protocol) and the data plane (who's in the room, what's being said, who raised their hand). Video Conferencing App is my full-stack take on both, built on Agora RTC + Socket.io + MongoDB.

Repo: github.com/SabarishR08/Video-Conferencing-App

The media plane: Agora RTC

  • Real-time video & audio calls via Agora RTC (agora-rtc-sdk-ng + agora-rtc-react)
  • Screen sharing so participants can present
  • Recording with RecordRTC, downloadable from the client
  • P2P fallback wired through peerjs for direct connections

The data plane: Socket.io + Agora RTM

  • Real-time chat during calls — Agora RTM for in-room messaging plus a Socket.io channel
  • Participant management — live lists of who's in the room, join/leave events, presence states
  • Room lifecycle — create a room instantly, join by ID, rooms persisted in MongoDB so they survive page reloads

Auth & persistence

  • JWT token auth with bcrypt-hashed passwords and protected routes on both client and server
  • User profiles with cookies (react-cookie) for session continuity
  • Mongoose models for users and rooms, controllers/routes split across the server (controllers/, middleware/, models/, routes/, socket/)

Architecture notes

The frontend is React 18 with Material-UI + Bootstrap components and React Router navigation; the backend is Express + Mongoose with a dedicated socket/ layer that owns the real-time event contract. That separation — media in Agora, presence in Socket.io, state in MongoDB — is the part I'd keep if I rebuilt it tomorrow.

What I'd do differently

  • TURN/relay fallback testing — Agora handles media transport, but the app should degrade gracefully when media is blocked and keep chat alive
  • Room permissions — hosts vs. participants, muting, and kicking are the natural next layer on top of the participant model
  • End-to-end encrypted chat — presence and signaling are fine plaintext on the wire in a demo; a real deployment wants E2EE on the message plane

It's the same real-time muscle as my freelancing marketplace (Socket.io events, JWT guards, rooms-as-state) — scaled up from text to full audio/video, which is where the interesting engineering starts.