A modern MVP for private messaging, contact discovery, and media sharing β built on a React frontend, an Express.js REST API, MongoDB for persistence, and Socket.IO for real-time messaging and presence.
Chatly is a full-stack real-time chat application designed as a modern MVP for private messaging. It combines a polished React client with a Node.js/Express API and a Socket.IO layer that powers instant messaging, typing indicators, and online presence. User data and messages are persisted in MongoDB, and media (profile pictures, shared images) is handled via Cloudinary.
The project demonstrates how a production-style chat product can be structured end-to-end: authentication, real-time transport, media handling, and a responsive UI, all working together as one cohesive application.
| Feature | Description |
|---|---|
| π Authentication | Secure JWT-based registration and login with cookie-backed sessions |
| β‘ Real-Time Messaging | Instant one-to-one delivery to online users via Socket.IO |
| βοΈ Typing Indicators | Live "user is typingβ¦" feedback in active conversations |
| π’ Online Presence | Real-time online/offline status for every contact |
| πΌοΈ Image Sharing | Send images in chat, stored and delivered via Cloudinary |
| ποΈ Seen Status | Messages marked as seen, with unread-count tracking per conversation |
| π Contact Search | Search contacts and filter to show online-only users |
| π Profile Management | Edit name/bio, upload a profile picture, and change password |
| π¨ Theme Toggle | Light/dark theme switch across the app |
| π± Responsive UI | Mobile-friendly sidebar + chat layout |
Screenshots live in the
/screenshotsfolder. Update or add new ones there and reference them the same way, e.g..
Chatly follows a two-tier architecture with a real-time transport layer running alongside the REST API:
ββββββββββββββββββββ βββββββββββββββββββββββββββββ
β React Client β ββββββΆ β Express.js API β
β (UI / Routing / β ββββββ β (Auth, Users, Messages, β
β Context state) β β Socket.IO server) β
ββββββββββββββββββββ βββββββββββββββ¬ββββββββββββββββ
β² β² β
β β Socket.IO (live events) β
β βββββββββββββββββββββββββββββββ
β βΌ
β βββββββββββββββ
β β MongoDB β
β β (Mongoose) β
β βββββββββββββββ
β
βΌ
ββββββββββββββββββββ
β Cloudinary β
β (image storage) β
ββββββββββββββββββββ
- Frontend Layer β React SPA handling auth flows, contact browsing, and the chat UI, with Context API providers for auth, chat, and socket state.
- Backend Layer β Node.js/Express REST API for auth, users, and messages, plus an embedded Socket.IO server broadcasting real-time events (messages, typing, presence).
- Data & Media Layer β MongoDB/Mongoose for persistent storage; Cloudinary for profile pictures and shared images.
Frontend: React, Vite, React Router, Tailwind CSS, Axios, Socket.IO Client, date-fns, emoji-picker-react, lucide-react Backend: Express.js, MongoDB, Mongoose, Socket.IO, JWT, bcryptjs, Multer, Cookie Parser Media: Cloudinary
Chatly/
βββ frontend/ # React + Vite client
β βββ src/
β β βββ context/ # Auth, Chat, and Socket context providers
β β βββ components/
β β βββ pages/
β β βββ App.jsx
β βββ ...
βββ backend/ # Express + Socket.IO server
β βββ routes/ # auth, users, messages
β βββ controllers/
β βββ models/ # Mongoose schemas
β βββ middleware/
β βββ lib/ # socket, cloudinary, db config
β βββ server.js
βββ README.md
Folder names above reflect the intended clean structure β see Roadmap for known cleanup items in the current repo layout.
- Node.js β₯ 18
- MongoDB (local or Atlas)
- A Cloudinary account (for image uploads)
- npm or yarn
-
Clone the repository
git clone https://github.com/wasay-khanzada/Chatly.git cd Chatly -
Set up the backend
cd backend npm installCreate a
.envfile inbackend/:PORT=5001 MONGODB_URI=your_mongodb_connection_string JWT_SECRET=your_jwt_secret NODE_ENV=development CLOUDINARY_CLOUD_NAME=your_cloudinary_cloud_name CLOUDINARY_API_KEY=your_cloudinary_api_key CLOUDINARY_API_SECRET=your_cloudinary_api_secret
npm run dev
-
Set up the frontend
cd ../frontend npm install npm run dev -
Open
http://localhost:5173in your browser.
| Method | Endpoint | Description |
|---|---|---|
| POST | /api/auth/register |
Register a new user |
| POST | /api/auth/login |
Authenticate and receive a JWT |
| POST | /api/auth/logout |
End the current session |
| GET | /api/auth/check |
Validate the current session |
| Method | Endpoint | Description |
|---|---|---|
| GET | /api/users |
Get contacts / searchable user list |
| PUT | /api/users/profile |
Update profile info and/or avatar |
| PUT | /api/users/password |
Change password |
| Method | Endpoint | Description |
|---|---|---|
| GET | /api/messages/:userId |
Get message history with a specific user |
| POST | /api/messages/send/:userId |
Send a text or image message |
| PUT | /api/messages/seen/:id |
Mark a message (or conversation) as seen |
Full request/response schemas can be documented separately (e.g. via Postman collection or OpenAPI spec).
| Event | Direction | Description |
|---|---|---|
getOnlineUsers |
Server β Client | Broadcasts the current list of online user IDs |
newMessage |
Server β Client | Pushes a newly sent message to the recipient |
typing |
Client β Client | Notifies the recipient that a user is typing |
stopTyping |
Client β Client | Clears the typing indicator |
messageSeen |
Client β Client | Updates seen status in real time |
- Standardize user field naming across frontend and backend
- Fix the typing flow to fully align the hook and UI behavior
- Add stronger input validation and security middleware
- Improve socket/presence scalability for multi-instance deployment (move off in-memory maps)
- Add automated tests (unit & integration)
- Add CI/CD and production deployment configuration
See open issues for a full list of proposed features and known issues.
Contributions are welcome! Please see CONTRIBUTING.md for guidelines on how to get started.
Distributed under the MIT License. See LICENSE for more information.
- Socket.IO β real-time communication
- Cloudinary β media hosting
- lucide-react β icons



