A full-stack, real-time messaging application built on the MERN stack. Supports one-on-one and group conversations, live typing indicators, online presence, media sharing, and rich message interactions (edit, reply, react, star, forward, delete) over a Socket.IO connection.
-
Real-time messaging — instant delivery via Socket.IO, with live typing indicators and online/offline presence
-
Authentication — JWT-based signup/login with password hashing (bcrypt)
-
Direct & group chats — create groups, add/remove members, assign an admin, and leave groups
-
Rich message actions — edit, delete, reply-to, forward, star/pin, and emoji reactions
-
Media support — image and audio messages uploaded via Cloudinary
-
Read receipts — messages marked as seen, with per-conversation unseen counts
-
User profiles — editable display name, bio, and profile picture
Client
-
React 19 + Vite
-
Tailwind CSS 4
-
React Router 7
-
Socket.IO Client
-
Axios
-
react-hot-toast
Server
-
Node.js + Express 5
-
MongoDB + Mongoose
-
Socket.IO
-
JSON Web Tokens (JWT)
-
bcryptjs
-
Cloudinary (media storage)
chat-app/
├── client/ # React frontend (Vite)
│ ├── src/
│ │ ├── components/ # Sidebar, ChatContainer, GroupChatContainer, RightSidebar
│ │ ├── pages/ # HomePage, LoginPage, ProfilePage
│ │ ├── context/ # AuthContext, ChatContext
│ │ └── lib/ # Client utilities
│ └── vercel.json
└── server/ # Express + Socket.IO backend
├── controllers/ # user, message, group controllers
├── models/ # User, Message, Group (Mongoose schemas)
├── routes/ # /api/auth, /api/messages, /api/groups
├── middleware/ # JWT auth guard
├── lib/ # db, socket, cloudinary, utils
├── server.js
└── vercel.json
-
Node.js (v18+)
-
A MongoDB instance (local or MongoDB Atlas)
-
A Cloudinary account for media uploads
git clone https://github.com/10bitsofwalid/chat-app.git
cd chat-appcd server
npm installCreate a .env file in server/:
MONGODB_URI=your_mongodb_connection_string
PORT=5000
JWT_SECRET=your_jwt_secret
CLOUDINARY_CLOUD_NAME=your_cloudinary_cloud_name
CLOUDINARY_API_KEY=your_cloudinary_api_key
CLOUDINARY_API_SECRET=your_cloudinary_api_secretRun the server in development mode:
npm run servercd ../client
npm installCreate a .env file in client/:
VITE_BACKEND_URL=http://localhost:5000Run the client:
npm run devThe app will be available at http://localhost:5173 (default Vite port), connecting to the API at the URL set in VITE_BACKEND_URL.
| Method | Endpoint | Description |
|---|---|---|
| POST | /api/auth/signup |
Register a new user |
| POST | /api/auth/login |
Authenticate and receive a token |
| GET | /api/auth/check |
Verify current session |
| PUT | /api/auth/update-profile |
Update profile info |
| GET | /api/messages/users |
Get sidebar user list with unseen counts |
| GET | /api/messages/:id |
Get conversation with a user |
| POST | /api/messages/send/:id |
Send a message |
| PUT | /api/messages/edit/:id |
Edit a message |
| PUT | /api/messages/mark/:id |
Mark a message as seen |
| POST | /api/messages/react/:id |
React to a message |
| POST | /api/messages/star/:id |
Star/unstar a message |
| POST | /api/messages/delete/:id |
Delete a message |
| POST | /api/messages/forward |
Forward message(s) |
| POST | /api/groups/create |
Create a group |
| GET | /api/groups |
List the user's groups |
| PUT | /api/groups/:id |
Update group details |
| POST | /api/groups/:id/add-member |
Add a member |
| POST | /api/groups/:id/remove-member |
Remove a member |
| POST | /api/groups/:id/leave |
Leave a group |
| POST | /api/groups/:id/message |
Send a group message |
| GET | /api/groups/:id/messages |
Get group message history |
All routes except signup, login, and /api/status require a valid JWT passed in the token request header.
Both client/ and server/ include vercel.json configs for deployment on Vercel. Deploy each as a separate project and point VITE_BACKEND_URL in the client's environment variables to the deployed server URL.
Walid Rahman
-
GitHub: https://github.com/10bitsofwalid
-
Portfolio: https://walid-rahman-portfolio.vercel.app
No license specified.