~/posts/video-conferencing-app
Video Conferencing App: Agora RTC, screen sharing, and live chat
- 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
peerjsfor 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.