Chatly is a feature-rich, full-stack real-time chat application built using the MERN stack (MongoDB, Express.js, React.js, Node.js) and Socket.io. It supports secure authentication, real-time 1-on-1 messaging, dynamic group chats, image sharing, audio voice notes, and active presence tracking.
Chatly features a modern, responsive, and vibrant UI powered by Tailwind CSS. The desktop interface provides a split sidebar layout (chats vs. groups), and transitioning to mobile dynamically scales down to a clean, focus-oriented message drawer.
- βοΈ React (Vite) β Component-based SPA framework
- π¨ Tailwind CSS β Styling and responsive utility design
- π Redux Toolkit β Centralized state management (users, groups, active messages, online status)
- π Socket.io Client β Persistent WebSockets connection layer
- π Emoji Picker React β Seamless emoji integrations
- π§ Node.js + Express.js β Server framework and REST API endpoints
- ποΈ MongoDB + Mongoose β NoSQL database schema representation and query ODM
- βοΈ Cloudinary β Cloud media storage for image and audio payloads
- π§± Multer β Handles multipart form-data parsing on uploads
- π Bcrypt.js β Secure password hashing logic
- π§© CORS & Cookie-Parser β Secure cross-origin requests and token cookie handling
- π Secure JWT Auth: User register, login, and profile modification with password hashing and cookies.
- π¬ Real-time 1-on-1 Chat: Instant messaging powered by WebSockets.
- π₯ Group Chats:
- Dynamic group creation selecting multiple members from active users.
- Participant Header Viewer: Lists participants under the group title.
- Interactive Members Modal: Clicking the header reveals a detailed modal of group members, highlighting the group admin and current user.
- π’ Presence system: Live online user indicator badges.
- πΌοΈ Image & Media Sharing: Upload images directly into the chat stream.
- ποΈ Voice Messaging: Record audio clips directly in-app and send them instantly to other users.
- ποΈ Chat Cleaners: Delete/clear chat history for both individual and group conversations.
graph TD
Client[React Client SPA] <-->|HTTP REST / Cookies| API[Express API Gateway]
Client <-->|WebSockets / Socket.io| SocketSrv[Socket.io Server]
API -->|Mongoose ODM| DB[(MongoDB Database)]
API -->|Uploads| Cloudinary[Cloudinary Media Service]
SocketSrv <-->|Reads/Writes Online Map| MemoryCache[In-Memory UserSocket Map]
- Initiation: On user login, the client establishes a persistent connection to the server passing the
userIdin the socket query parameters. - Presence Tracking: The server maps the
userIdto its activesocket.idinside a memory dictionary (userSocketMap) and immediately broadcasts the updatedgetOnlineUserslist to all connected clients. - Dispatching Message Events:
- For 1-on-1 messages: The backend looks up the recipient's
socket.idand emits anewMessageevent exclusively to them. - For Group messages: The backend traverses all group participant IDs, retrieves their active socket IDs, and emits a
newMessageevent to each member.
- For 1-on-1 messages: The backend looks up the recipient's
- Disconnection: When a socket disconnects, their ID is removed from the memory map and a fresh online list is sent out.
βββ backend/
β βββ config/ # DB connection & Cloudinary setup
β βββ controllers/ # Express handlers (auth, messages, user groups)
β βββ middlewares/ # JWT Authentication, Multer file upload filters
β βββ models/ # Mongoose DB Schemas
β βββ routes/ # API Endpoint Routing
β βββ socket/ # Socket.io connection handlers and socket map
β βββ index.js # Main backend entry point
βββ frontend/
βββ src/
βββ assets/ # Static assets and images
βββ components/ # UI Components (MessageArea, Sidebar, message cells)
βββ customHooks/ # Reusable API fetch wrappers (groups list)
βββ pages/ # App Pages (Home, Login, Register, Profile)
βββ redux/ # Redux Toolkit global store and slices
βββ main.jsx # Frontend entry point
{
name: String,
userName: { type: String, unique: true },
email: { type: String, unique: true },
password: { type: String, required: true },
image: { type: String, default: "" }
}{
sender: { type: ObjectId, ref: "User" },
receiver: { type: ObjectId, ref: "User" }, // omitted for group messages
conversationId: { type: ObjectId, ref: "Conversation" }, // populated for group messages
message: { type: String, default: "" },
image: { type: String, default: "" },
audio: { type: String, default: "" }
}Note: The participants field is named
partcipants(missing the first 'i') within the schema.
{
partcipants: [{ type: ObjectId, ref: "User" }],
messages: [{ type: ObjectId, ref: "Message" }],
isGroup: { type: Boolean, default: false },
groupName: { type: String, default: "" },
groupAdmin: { type: ObjectId, ref: "User" },
groupImage: { type: String, default: "" }
}- Node.js installed locally.
- MongoDB Instance (Local or MongoDB Atlas connection URL).
- Cloudinary Account (for media uploads).
git clone https://github.com/Samagra12725/RealTimeChatApp.git
cd RealTimeChatAppCreate a .env file in the backend/ folder:
PORT=5000
MONGO_URI=your_mongodb_connection_string
JWT_SECRET=your_jwt_signing_key
CLOUDINARY_CLOUD_NAME=your_cloudinary_name
CLOUDINARY_API_KEY=your_cloudinary_api_key
CLOUDINARY_API_SECRET=your_cloudinary_api_secretcd backend
npm install
npm run dev # Launches server on port 5000cd ../frontend
npm install
npm run dev # Launches dev server on port 5173Samagra Jaiswal
- Software Developer | MERN Stack Specialist
- GitHub: @Samagra12725