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!