Production-ready, full-stack real-time messaging and calling platform built with React (Vite) on the frontend and Node.js/Express + MongoDB on the backend. Features secure JWT auth, OTP verification, WebRTC voice/video calls, file uploads, and a polished responsive UI. Built with care by Najb Yassine.
- Features
- Tech Stack
- Architecture
- Project Structure
- Getting Started
- Environment Variables
- Available Scripts
- Testing & Quality
- Deployment Notes
- Security Checklist
- Future Enhancements
- Email signup with OTP verification, JWT auth (HTTP-only cookies), password reset.
- Real-time messaging: text, images, files, replies, reactions, unread counts, presence.
- One-on-one voice & video calls via WebRTC (screen share, mute/video toggle, call state).
- Zustand-managed global state with optimistic updates and Socket.io listeners.
- Cloudinary-backed media storage, Multer uploads, transactional email templates.
- Responsive Tailwind + DaisyUI interface with dark/light themes, skeletons, toast notifications.
Frontend: React 18, Vite, React Router, Zustand, Socket.io-client, Simple Peer Light, Tailwind CSS, DaisyUI, Framer Motion, Axios, React Hot Toast
Backend: Node.js, Express, MongoDB, Mongoose, Socket.io, JWT, bcryptjs, Multer, Cloudinary SDK, Nodemailer, OTPLIB, cookie-parser, cors
Tooling: ESLint, Nodemon, dotenv, Vite build pipeline
React SPA ⇄ REST API (Express) ⇄ MongoDB
↓ ↓
Socket.io (websocket) Cloudinary / Nodemailer
↓
WebRTC peer-to-peer media
- Frontend and backend are fully decoupled; they communicate via REST for persistence and Socket.io for live events.
- Socket.io handles presence, new messages, and call signalling (offer/answer/ICE/end events).
- WebRTC connections (Simple Peer + optional ZEGOCLOUD SDK) stream audio/video directly between peers.
- JWT is stored in HTTP-only cookies; middleware guards all sensitive routes.
Project/
├── Back_End/ # Node.js API + Socket.io server
│ ├── src/controllers
│ ├── src/routes
│ ├── src/models
│ ├── src/middleware
│ ├── src/lib
│ └── src/template
├── Front_End/ # React 18 + Vite client
│ ├── src/components
│ ├── src/pages
│ ├── src/store
│ ├── src/lib
│ └── src/constants
└── README.md # (this file)
Each subdirectory (Back_End and Front_End) contains its own detailed README with service-specific instructions.
git clone <repo-url>
cd Project
# Backend
cd Back_End
npm install
# Frontend
cd ../Front_End
npm install- Copy
.env.example(if you add one) or follow the table below to create.envfiles inside bothBack_End/andFront_End/. - Never commit these files.
# Terminal 1 - backend
cd Back_End
npm run dev # runs on http://localhost:5001
# Terminal 2 - frontend
cd Front_End
npm run dev # runs on http://localhost:5173Frontend expects the backend at http://localhost:5001 and opens sockets to the same origin (configurable via env vars).
| Location | Key | Description |
|---|---|---|
| Back_End | PORT |
API port (default 5001) |
| Back_End | NODE_ENV |
development or production |
| Back_End | MONGODB_URI |
MongoDB connection string |
| Back_End | JWT_SECRET |
Long random string for token signing |
| Back_End | OTP_SECRET |
Seed for OTP generation |
| Back_End | EMAIL_USER / EMAIL_PASS |
SMTP credentials (e.g., Gmail App Password) |
| Back_End | CLOUDINARY_CLOUD_NAME / CLOUDINARY_API_KEY / CLOUDINARY_API_SECRET |
Cloudinary account credentials |
| Back_End | FRONTEND_URL |
e.g., http://localhost:5173 used in emails/reset links |
| Back_End | CLIENT_URL |
Allowed origin for CORS/Socket.io |
| Front_End | VITE_API_URL |
REST base (default http://localhost:5001/api) |
| Front_End | VITE_SOCKET_URL |
Socket.io server URL |
| Front_End | VITE_ZEGO_APP_ID, VITE_ZEGO_APP_SIGN, VITE_ZEGO_SERVER, VITE_ZEGO_TEMP_TOKEN |
If using ZEGOCLOUD SDK |
Adapt names as needed; Vite only exposes variables prefixed with VITE_.
| Location | Command | Description |
|---|---|---|
| Back_End | npm run dev |
Nodemon development server |
| Back_End | npm run start |
Production start (Node) |
| Front_End | npm run dev |
Vite dev server with HMR |
| Front_End | npm run build |
Production build to dist/ |
| Front_End | npm run preview |
Preview built assets |
| Front_End | npm run lint |
ESLint scan |
- Manual QA: run two browser sessions to validate messaging/calling flows, including offline scenarios.
- Linting:
npm run lintinsideFront_End. Add ESLint/Prettier for backend if desired. - API testing: Postman/Insomnia collections for auth/message routes (see Back_End README for endpoints).
- Socket testing: Use browser devtools or node scripts leveraging
socket.io-client.
- Build the frontend (
npm run build) and either:- Serve
Front_End/distfrom a static host (Netlify/Vercel) pointing API calls to a deployed backend. - Or copy
dist/into the backend and let Express serve static files (already supported insrc/index.jswhenNODE_ENV=production).
- Serve
- Set all env vars in your hosting environment (Docker secrets, GitHub Actions, cloud provider).
- Use HTTPS for WebRTC (required by browsers).
- Configure a process manager (PM2/systemd) or container orchestration for the backend.
- Add SSL termination and load balancing (NGINX, Cloudflare) as you scale.
- Never commit
.env, API keys, access tokens, or ZEGOCLOUD credentials. - Replace the hard-coded
appID,appSign, and token placeholder inFront_End/src/lib/zego.jswith env-driven values (and avoid storing the real secrets in Git). - Lock down CORS to trusted origins before production.
- Ensure cookies use
secure: true+sameSite: strictin production. - Rotate JWT/OTP/email credentials regularly.
- Sanitize logs to prevent leaking user data or tokens.
- Group chats and group calls
- Push notifications (web/mobile)
- End-to-end encryption
- Message search and filtering
- React Native companion app
- Read receipts / typing indicators / message delivery states
-BlackPanther Made By Najb Yassine