A real-time chat application built with a microservices architecture, featuring email-based OTP authentication, live messaging, image sharing, typing indicators, and online presence tracking.
Traditional chat apps bundle all logic into a single monolith, making them hard to scale and maintain. RelayChat separates concerns into independent services โ a User Service, a Chat Service, and a Mail Service โ each deployable and scalable independently.
- ๐ง Email OTP Login โ Passwordless authentication via 6-digit OTP sent to email
- โก Real-time Messaging โ Instant delivery via Socket.IO
- ๐ผ๏ธ Image Sharing โ Upload and send images via Cloudinary
- โ Read Receipts โ Messages are marked as seen with timestamps
- ๐ข Online Presence โ See which users are currently online
- โจ๏ธ Typing Indicators โ Live "user is typing..." feedback
- ๐ JWT Authentication โ Stateless auth with 15-day token expiry
- ๐ฆ OTP Rate Limiting โ Redis-backed 1 OTP per email per minute
- ๐ค Profile Management โ Update your display name
| Layer | Technology |
|---|---|
| Frontend | Next.js 16 (App Router), React 19, TypeScript, Tailwind CSS |
| Backend | Node.js, Express.js v5, TypeScript |
| Real-time | Socket.IO |
| Database | MongoDB (Mongoose) |
| Cache / Rate Limit | Redis (Upstash) |
| Message Queue | RabbitMQ (via AMQP / Docker) |
| Nodemailer (Gmail SMTP) | |
| Media Upload | Cloudinary + Multer |
| Auth | JWT (jsonwebtoken) |
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ Next.js Frontend โ
โ (Login โ Verify โ Chat Page) โ
โโโโโโโโโฌโโโโโโโโโโโฌโโโโโโโโโโโโโโโ
โ HTTP โ WebSocket (Socket.IO)
โผ โผ
โโโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโโโโโโ
โ User Serviceโ โ Chat Service โ
โ (Port 5000) โ โ (Port 5002) โ
โ โ โ โ
โ MongoDB โ โ MongoDB โ
โ Redis โ โ Socket.IO โ
โ RabbitMQ โ โ Cloudinary โ
โโโโโโโโฌโโโโโโโโ โโโโโโโโโโโโโโโโโโโโ
โ publishes to queue
โผ
โโโโโโโโโโโโโโโโ
โ Mail Serviceโ โ consumes RabbitMQ queue
โ (Port 3001) โ sends OTP via Gmail SMTP
โโโโโโโโโโโโโโโโ
The Chat Service makes internal HTTP calls to the User Service (via axios) to fetch user profile data when loading chats and messages.
Chat App/
โโโ backend/
โ โโโ user/ # User Service (Port 5000)
โ โ โโโ src/
โ โ โโโ index.ts # Express app entry, Redis + RabbitMQ setup
โ โ โโโ config/
โ โ โ โโโ db.ts # MongoDB connection
โ โ โ โโโ rabbitmq.ts # RabbitMQ publisher
โ โ โ โโโ generateToken.ts # JWT generator
โ โ โ โโโ tryCatch.ts # Global error wrapper
โ โ โโโ model/user.ts # User schema (name, email)
โ โ โโโ controllers/user.ts # loginUser, verifyUser, myProfile, updateName, ...
โ โ โโโ middleware/isauth.ts # JWT auth middleware
โ โ โโโ routes/user.ts # Route definitions
โ โ
โ โโโ chat/ # Chat Service (Port 5002)
โ โ โโโ src/
โ โ โโโ index.ts # Express app entry
โ โ โโโ config/
โ โ โ โโโ db.ts # MongoDB connection
โ โ โ โโโ socket.ts # Socket.IO server setup
โ โ โ โโโ cloudinary.ts # Cloudinary config
โ โ โโโ models/
โ โ โ โโโ chat.ts # Chat schema (users[], latestMessage)
โ โ โ โโโ messages.ts # Message schema (text/image, seen, seenAt)
โ โ โโโ controllers/chat.ts # createNewChat, getAllChats, sendMessage, getMessagesByChat
โ โ โโโ middlewares/
โ โ โ โโโ isAuth.ts # JWT auth middleware
โ โ โ โโโ multer.ts # Cloudinary-backed file upload
โ โ โโโ routes/chat.ts # Route definitions
โ โ
โ โโโ mail/ # Mail Service (Port 3001)
โ โโโ src/
โ โโโ index.ts # Express app entry
โ โโโ consumer.ts # RabbitMQ consumer โ Nodemailer email sender
โ
โโโ frontend/ # Next.js App
โโโ app/
โโโ layout.tsx # Root layout (AppProvider + SocketProvider)
โโโ page.tsx # Root redirect
โโโ login/page.tsx # Email input page
โโโ verify/page.tsx # OTP verification page
โโโ chat/page.tsx # Main chat interface
โโโ profile/page.tsx # Profile/name edit page
โโโ context/
โ โโโ appContext.tsx # Global state (user, chats, auth)
โ โโโ SocketContext.tsx # Socket.IO client provider
โโโ components/
โโโ ChatSidebar.tsx # Chat list + user list panel
โโโ ChatHeader.tsx # Active chat header + typing indicator
โโโ ChatMessages.tsx # Message bubbles with seen receipts
โโโ MessageInput.tsx # Text + image upload input
โโโ verifyOtp.tsx # 6-digit OTP input logic
โโโ Loading.tsx # Loading spinner
- Node.js โฅ 18
- Docker (for RabbitMQ)
- MongoDB (Atlas or local)
- Redis (Upstash or local)
- Cloudinary account
- Gmail account (with App Password)
git clone https://github.com/theUtkarshRaj/RelayChat.git
cd "Chat App"docker run -d --hostname rabbitmq-host --name rabbitmq-container \
-e RABBITMQ_DEFAULT_USER=admin \
-e RABBITMQ_DEFAULT_PASS=admin123 \
-p 5672:5672 -p 15672:15672 \
rabbitmq:3-management# User Service
cd backend/user && npm install
# Chat Service
cd ../chat && npm install
# Mail Service
cd ../mail && npm install
# Frontend
cd ../../frontend && npm installPORT=5000
MONGO_URI=mongodb+srv://<user>:<pass>@cluster.mongodb.net/
REDIS_URL=redis://<upstash-url>
JWT_SECRET=your_jwt_secret
Rabbitmq_Host=localhost
Rabbitmq_Username=admin
Rabbitmq_Password=admin123PORT=5002
MONGO_URI=mongodb+srv://<user>:<pass>@cluster.mongodb.net/
JWT_SECRET=your_jwt_secret
USER_SERVICE=http://localhost:5000
CLOUD_NAME=your_cloudinary_cloud_name
API_KEY=your_cloudinary_api_key
API_SECRET=your_cloudinary_api_secretport=3001
Rabbitmq_Host=localhost
Rabbitmq_Username=admin
Rabbitmq_Password=admin123
USER=your_gmail@gmail.com
PASSWORD=your_gmail_app_password
โ ๏ธ Use a Gmail App Password (not your regular Gmail password). Enable 2FA on your Google account and generate an App Password.
Open 4 terminals simultaneously:
# Terminal 1 โ User Service
cd backend/user
npm run dev
# Terminal 2 โ Chat Service
cd backend/chat
npm run dev
# Terminal 3 โ Mail Service
cd backend/mail
npm run dev
# Terminal 4 โ Frontend
cd frontend
npm run devVisit: http://localhost:3000
| Method | Route | Auth | Description |
|---|---|---|---|
| POST | /login |
โ | Send OTP to email |
| POST | /verify |
โ | Verify OTP, return JWT + user |
| GET | /me |
โ | Get logged-in user profile |
| GET | /user/all |
โ | Get all users |
| GET | /user/:id |
โ | Get single user by ID |
| POST | /update/user |
โ | Update display name |
| Method | Route | Auth | Description |
|---|---|---|---|
| POST | /chat/new |
โ | Create or fetch a 1-to-1 chat |
| GET | /chat/all |
โ | Get all chats for logged-in user |
| POST | /message |
โ | Send a text or image message |
| GET | /message/:chatId |
โ | Get all messages in a chat |
| Event (emit) | Direction | Description |
|---|---|---|
joinChat |
Client โ Server | Join a chat room |
leaveChat |
Client โ Server | Leave a chat room |
typing |
Client โ Server | Notify typing started |
stopTyping |
Client โ Server | Notify typing stopped |
newMessage |
Server โ Client | Broadcast new message |
messagesSeen |
Server โ Client | Notify messages marked seen |
getOnlineUser |
Server โ Client | Broadcast online users list |
userTyping |
Server โ Client | Broadcast typing event |
- Login Page โ Dark themed, email-only input with a blue submit button to send OTP
- Verify Page โ 6 individual OTP digit boxes with auto-focus, paste support, and a 60-second resend timer
- Chat Page โ Two-panel layout: left sidebar (chats / all-users toggle) and right message area with header, message bubbles, and input bar
- Profile Page โ Shows current name with an edit form to update it
- Group chat support
- Voice / video calling (WebRTC)
- Push notifications (FCM)
- Message deletion / editing
- End-to-end encryption
- Docker Compose for one-command startup
- CI/CD pipeline
- Profile picture upload
- Search messages
Utkarsh Raj GitHub: @theUtkarshRaj