A modern, full-stack real-time chat application built with Next.js 16, Express, Socket.IO, Redis, and MongoDB. Features instant messaging, room-based conversations, user authentication, message persistence, and a sleek, responsive UI.
- Real-time Messaging: Instant message delivery using Socket.IO with WebSocket protocol
- Room-Based Chat: Create and join different chat rooms dynamically
- User Authentication: Secure authentication powered by NextAuth v5
- Message Persistence: Chat history stored in MongoDB with automatic 7-day cleanup
- Message History: Load last 50 messages when joining a room
- Typing Indicators: Live feedback when other users are typing
- User Presence: Real-time join/leave notifications and online status
- Toast Notifications: User-friendly alerts for all chat events
- Scalable Architecture: Redis Pub/Sub enables horizontal scaling across multiple server instances
- TypeScript: Full type safety across frontend and backend
- Modern UI: Beautiful, responsive interface built with Tailwind CSS v4
- State Management: Lightweight client state with Zustand
- Session Management: Secure session handling with NextAuth
- Auto-reconnect: Robust WebSocket reconnection logic
- Indexed Queries: Optimized MongoDB queries with compound indexes
Frontend
- Framework: Next.js 16.1.1 (App Router)
- UI Library: React 19.2.3
- Styling: Tailwind CSS v4
- State Management: Zustand
- Authentication: NextAuth v5 (beta)
- Real-time: Socket.IO Client
- Icons: Lucide React, React Icons
- Notifications: React Hot Toast
Backend
- Runtime: Node.js with Express
- Real-time Engine: Socket.IO Server
- Message Broker: Redis (Pub/Sub)
- Database: MongoDB with Mongoose
- Environment: dotenv
- CORS: Enabled for cross-origin requests
┌─────────────────┐
│ Next.js App │
│ (Frontend) │
└────────┬────────┘
│ Socket.IO
↓
┌─────────────────┐ ┌──────────┐
│ Express Server │◄────►│ Redis │
│ + Socket.IO │ │ Pub/Sub │
└────────┬────────┘ └──────────┘
│
↓
┌─────────┐
│ MongoDB │
└─────────┘
Flow:
- User connects via Socket.IO from Next.js frontend
- Express server handles WebSocket connections
- Messages published to Redis channels for scalable distribution
- All server instances subscribe to relevant Redis channels
- Messages saved to MongoDB for persistence
- Redis broadcasts events to all connected clients in the room
- Node.js 20+ (with npm/yarn/pnpm)
- MongoDB (local or Atlas cluster)
- Redis (local or cloud instance)
-
Clone the repository
git clone <repository-url> cd Chat-App/chat-app
-
Install frontend dependencies
npm install
-
Install backend dependencies
cd server npm install cd ..
Create a .env.local file in the chat-app directory:
# NextAuth Configuration
NEXTAUTH_URL=http://localhost:3000
NEXTAUTH_SECRET=your-secret-key-here
# Socket.IO Server URL
NEXT_PUBLIC_SOCKET_URL=http://localhost:8000
# OAuth Providers (optional - configure in auth.config.ts)
# GITHUB_ID=your-github-client-id
# GITHUB_SECRET=your-github-client-secretCreate a .env file in the chat-app/server directory:
# Server Configuration
PORT=8000
CORS_ORIGIN=http://localhost:3000
# MongoDB Connection
MONGODB_URI=mongodb://localhost:27017/chatapp
# Or use MongoDB Atlas:
# MONGODB_URI=mongodb+srv://username:[email protected]/chatapp
# Redis Configuration
REDIS_HOST=localhost
REDIS_PORT=6379
# For cloud Redis (e.g., Upstash):
# REDIS_URL=redis://username:password@host:port-
Start the backend server (in
chat-app/server):cd server npm run devServer will run on
http://localhost:8000 -
Start the frontend (in
chat-app):npm run dev
App will run on
http://localhost:3000 -
Access the app
- Open http://localhost:3000
- Sign in with your configured authentication provider
- Join a room (e.g., "general", "random", etc.)
- Start chatting!
Frontend:
npm run build
npm startBackend:
cd server
npm run build
npm startchat-app/
├── src/
│ ├── app/ # Next.js App Router pages
│ │ ├── api/auth/ # NextAuth API routes
│ │ ├── chat/ # Chat page
│ │ ├── signin/ # Sign-in page
│ │ └── page.tsx # Landing page
│ ├── components/
│ │ ├── chat/ # Chat UI components
│ │ │ ├── ChatWindow.tsx
│ │ │ ├── MessageBubble.tsx
│ │ │ ├── MessageInput.tsx
│ │ │ └── UserList.tsx
│ │ ├── landing/ # Landing page components
│ │ └── providers/ # Context providers
│ ├── hooks/
│ │ └── useSocket.ts # Socket.IO hook
│ ├── store/
│ │ └── chatStore.ts # Zustand state management
│ ├── types/ # TypeScript type definitions
│ ├── auth.config.ts # NextAuth configuration
│ └── middleware.ts # Next.js middleware
├── server/
│ └── src/
│ ├── index.ts # Express + Socket.IO server
│ ├── db.ts # MongoDB connection
│ ├── redis.ts # Redis Pub/Sub setup
│ └── models/
│ └── Message.ts # Mongoose message model
└── public/ # Static assets
Configure authentication providers in src/auth.config.ts. Currently supports:
- GitHub OAuth
- Google OAuth (can be added)
- Email/Magic Links (can be added)
Messages are stored with the following schema:
{
messageId: string; // Unique message ID
roomId: string; // Chat room identifier
userId: string; // Sender's socket ID
username: string; // Sender's display name
content: string; // Message text
timestamp: number; // Unix timestamp
createdAt: Date; // Auto-generated
}Messages auto-expire after 7 days (configurable in Message.ts).
Each room has a dedicated Redis channel: room:{roomId}
Published events:
user-joined: User enters a roomuser-left: User exits a roomreceive-message: New message sentuser-typing: Typing indicatoruser-disconnected: Socket disconnect
- Modify
src/app/globals.cssfor global styles - Update
tailwind.config.tsfor theme customization - Component styles use Tailwind utility classes
- Adjust message history limit in
server/src/index.ts(currently 50) - Change message TTL in
server/src/models/Message.ts(currently 7 days) - Customize typing timeout in
src/app/chat/page.tsx(currently 1 second)
- Push code to GitHub
- Import project in Vercel
- Add environment variables
- Deploy
- Deploy
serverdirectory - Set environment variables
- Ensure MongoDB and Redis are accessible
- Update
NEXT_PUBLIC_SOCKET_URLin frontend
- MongoDB: Use MongoDB Atlas (free tier available)
- Redis: Use Upstash or Redis Cloud (free tier available)
- Verify
NEXT_PUBLIC_SOCKET_URLmatches your backend URL - Check CORS settings in
server/src/index.ts - Ensure backend server is running
- Confirm
NEXTAUTH_URLandNEXTAUTH_SECRETare set - Verify OAuth provider credentials
- Check session configuration in
auth.config.ts
- Verify
MONGODB_URIis correct - Ensure MongoDB is running (local) or accessible (cloud)
- Check network/firewall settings
- Confirm Redis is running (
redis-server) - Verify
REDIS_HOSTandREDIS_PORT - For cloud Redis, use
REDIS_URLinstead
This project is open source and available under the MIT License.
Contributions, issues, and feature requests are welcome!
Built with ❤️ using Next.js, Socket.IO, Redis, and MongoDB