A production-grade, real-time chat platform built with the MERN stack
⚡ Real-time messaging • 👥 Group chats • 🤬 Profanity filter • 🔒 JWT auth • ☁️ Image uploads • 🌗 Dark/Light mode
- Features
- Tech Stack
- Architecture
- Getting Started
- Abuse Word Masker
- API Reference
- Deployment
- Project Structure
- Contributing
|
|
- Modern responsive UI styled with Tailwind CSS
- Dedicated Dark / Light mode toggles with glassmorphism tokens
- Production-ready split-domain deployment (Vercel + Render)
┌─────────────────────────────────────────────────────────────────┐
│ CLIENT (React + Vite) │
│ │
│ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────────┐ │
│ │ Pages │ │Components│ │ Hooks │ │ Zustand Store│ │
│ └────┬─────┘ └────┬─────┘ └────┬─────┘ └──────┬───────┘ │
│ │ │ │ │ │
│ └──────────────┴─────────────┴───────────────┘ │
│ │ Axios (REST) │ Socket.io-client │
└────────────────────┼────────────────────┼───────────────────────┘
│ │
▼ ▼
┌────────────────────────────────────────────────────────────────┐
│ SERVER (Node.js + Express) │
│ │
│ ┌──────────┐ ┌──────────┐ ┌───────────┐ ┌────────────┐ │
│ │ Routes │→ │Controllers│→ │ Services │→ │ Models │ │
│ └──────────┘ └──────────┘ └─────┬─────┘ └─────┬──────┘ │
│ │ │ │
│ ┌──────┴──────┐ │ │
│ │AbuseMasker │ │ │
│ │(Trie Filter)│ │ │
│ └─────────────┘ │ │
│ │ │
│ ┌──────────────┐ ┌────────────┐ │ │
│ │ Socket.io │ │ Passport │ │ │
│ │ (WebSocket) │ │ (JWT Auth) │ │ │
│ └──────────────┘ └────────────┘ │ │
└─────────────────────────────────────────┬──────────────────────┘
│
▼
┌──────────────────┐
│ MongoDB │
│ ┌────────────┐ │
│ │ Users │ │
│ │ Chats │ │
│ │ Messages │ │
│ │ AbuseWords │ │
│ └────────────┘ │
└──────────────────┘
| Requirement | Version |
|---|---|
| Node.js | >= 18.x |
| MongoDB | Atlas cluster or local instance |
| Cloudinary account | Free tier works |
git clone https://github.com/your-username/MERN-RealTime-Messagers-Platform.git
cd MERN-RealTime-Messagers-Platformcd backend
npm installCreate a .env file in the backend/ directory:
PORT=8000
NODE_ENV=development
MONGO_URI=your_mongodb_connection_string
JWT_SECRET=your_super_secret_key
JWT_EXPIRES_IN=1d
FRONTEND_ORIGIN=http://localhost:5173
# Cloudinary (required for image uploads)
CLOUDINARY_CLOUD_NAME=your_cloud_name
CLOUDINARY_API_KEY=your_api_key
CLOUDINARY_API_SECRET=your_api_secretSeed the abuse word list (one-time):
npx ts-node src/script/seedAbuseWords.tsStart the backend:
npm run devYou should see:
Abuse masker loaded 72 words into Triefollowed byServer running on port 8000
cd client
npm installCreate a .env.local file in client/ (optional — defaults to http://localhost:8000/api):
VITE_API_URL=http://localhost:8000/apiStart the frontend:
npm run devNavigate to http://localhost:5173 — you're live! 🎉
A server-side profanity filter that automatically detects and masks abusive language in chat messages before they are stored or broadcast. Zero client-side changes required.
User types: "you are a chutiya"
│
▼
POST /api/chat/message/send
│
▼
sendMessageService()
│
▼
┌───────────────────────────────┐
│ abuseMasker.mask(content) │
│ │
│ Trie lookup per word: │
│ "you" → ✗ (pass) │
│ "are" → ✗ (pass) │
│ "a" → ✗ (pass) │
│ "chutiya" → ✓ (MATCH!) │
│ │
│ Output: "you are a *******" │
└───────────────────────────────┘
│
┌─────────┴─────────┐
▼ ▼
Save to MongoDB WebSocket broadcast
(masked content) (masked content)
| Approach | Time Complexity | 1000 words × 50-word message |
|---|---|---|
| Brute-force list scan | O(n × m) | 50,000 comparisons |
| Regex alternation | O(n × m) | Regex backtracking overhead |
| Trie lookup ✅ | O(m) per word | 50 lookups (word-length only) |
The Trie provides constant-time lookups regardless of how many abuse words are in the dictionary.
| Component | File | Purpose |
|---|---|---|
| 🌳 Trie + Masker | backend/src/lib/abuseMasker.ts |
Singleton — builds Trie from DB, provides mask(text) |
| 📄 MongoDB Model | backend/src/models/abuseWord.model.ts |
Stores words with unique lowercase index |
| 🌱 Seed Script | backend/src/script/seedAbuseWords.ts |
Pre-populates ~72 English + Hindi profanity words |
| 🔌 Admin API | backend/src/routes/abuseWord.route.ts |
REST endpoints to view/add words at runtime |
| 🔗 Integration | backend/src/services/message.service.ts |
Hooks masker into the message pipeline |
| Decision | Rationale |
|---|---|
| Trie data structure | O(m) per-word lookup — scales to any dictionary size |
| Word-boundary splitting | \b regex split prevents "class" being flagged by "ass" |
| Server-side only | Masked before DB write — all clients always see clean text |
| Case-insensitive | "FUCK", "Fuck", "fuck" are all caught identically |
| Hot-reload | Admin API reloads Trie instantly — no server restart needed |
| Asterisk matching | Replacement length matches original word (shit → ****) |
cd backend
npx ts-node src/script/seedAbuseWords.ts✓ Database connected for seeding
✓ Successfully seeded 72 abuse words
✓ Total abuse words in database: 72
✓ Database disconnected
Includes English profanity, slurs, and common Hindi/Indian abuse words. Duplicates are automatically skipped on re-runs.
| Method | Endpoint | Description |
|---|---|---|
POST |
/api/auth/register |
Register a new user |
POST |
/api/auth/login |
Log in and receive JWT cookie |
POST |
/api/auth/logout |
Clear auth cookie |
| Method | Endpoint | Description |
|---|---|---|
POST |
/api/chat/create |
Create a new chat (1-to-1 or group) |
GET |
/api/chat/all |
Get all chats for the authenticated user |
GET |
/api/chat/:id |
Get a single chat with message history |
POST |
/api/chat/message/send |
Send a message (auto-masked for profanity) |
| Method | Endpoint | Body | Description |
|---|---|---|---|
GET |
/api/abuse-words |
— | List all abuse words |
POST |
/api/abuse-words/add |
{ "words": ["word1", "word2"] } |
Add words & hot-reload Trie |
🔒 All endpoints (except register/login) require JWT authentication via HTTP-Only cookie.
| Event | Direction | Payload | Description |
|---|---|---|---|
online:users |
Server → Client | string[] |
Broadcast online user IDs |
chat:join |
Client → Server | chatId |
Join a chat room |
chat:leave |
Client → Server | chatId |
Leave a chat room |
chat:new |
Server → Client | Chat |
New chat created |
chat:update |
Server → Client | { chatId, lastMessage } |
Chat updated with new message |
message:new |
Server → Client | Message |
New message in chat room |
This repository is configured for split-domain deployment — separating the frontend (static) from the backend (WebSocket-capable).
Backend → Render.com
A render.yaml Blueprint is included at the project root.
- Import the repository into Render as a New Blueprint
- Render auto-detects the backend service
- Set environment variables in the Dashboard
- Set
FRONTEND_ORIGINto your Vercel URL (no trailing/)
- Set
Frontend → Vercel
- Import the repository into Vercel
- Set Root Directory to
client - Set
VITE_API_URLto your Render backend URL (e.g.,https://your-backend.onrender.com/api) - Deploy 🚀
A
vercel.jsonrewrite config is included in/clientso SPA routes like/chatnever 404.
MERN-RealTime-Messagers-Platform/
├── backend/
│ └── src/
│ ├── config/ # Database, env, cloudinary, passport configs
│ ├── controllers/ # Route handlers (auth, chat, message, abuseWord)
│ ├── lib/
│ │ ├── socket.ts # Socket.io server initialization & events
│ │ └── abuseMasker.ts # 🌳 Trie-based profanity filter (singleton)
│ ├── middlewares/ # Auth, error handling, async wrapper
│ ├── models/ # Mongoose schemas (User, Chat, Message, AbuseWord)
│ ├── routes/ # Express route definitions
│ ├── script/
│ │ └── seedAbuseWords.ts # 🌱 Database seeder for abuse words
│ ├── services/ # Business logic layer
│ ├── utils/ # Helpers (bcrypt, cookies, env)
│ ├── validators/ # Zod request schemas
│ └── index.ts # Server entry point
├── client/
│ └── src/
│ ├── components/ # Reusable UI components
│ ├── hooks/ # Custom React hooks (auth, chat, socket)
│ ├── layouts/ # Page layout wrappers
│ ├── lib/ # Axios client, helpers, utils
│ ├── pages/ # Route-level page components
│ ├── routes/ # React Router configuration
│ ├── types/ # TypeScript type definitions
│ └── App.tsx # Root component
├── render.yaml # Render deployment blueprint
└── vercel.json # Vercel deployment config
Contributions are welcome! Please feel free to submit a Pull Request.
- Fork the repository
- Create your feature branch (
git checkout -b feature/amazing-feature) - Commit your changes (
git commit -m 'Add amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
Built with ❤️ using the MERN Stack
⭐ Star this repo if you found it useful!