A full-stack real-time chat application built with the MERN stack and Socket.io.
Pulse is a real-time messaging web application that lets users register, sign in, and chat with others instantly. Messages and images are delivered live over WebSockets. Users can personalise their experience with built-in DaisyUI themes and manage their profile picture via Cloudinary.
Pulse uses JWT-based authentication stored in HTTP-only cookies. Both sign-in and sign-up forms include inline icon hints and show/hide password toggle for a smooth user experience.
Messages are delivered instantly with Socket.io. You can see which contacts are online, send text and images (up to 5 MB), and scroll through your conversation history.
Users can update their display name and upload a profile picture directly from the Profile page. Pictures are stored and served through Cloudinary.
Pulse ships with 32 DaisyUI themes selectable from the Settings page. A live preview updates immediately so you can pick the look that suits you before confirming.
- Node.js 18+
- A MongoDB Atlas account
- A Cloudinary account
git clone https://github.com/aliemrepmk/pulse.git
cd pulsecd backend
cp .env.example .envOpen backend/.env and fill in your values:
MONGODB_URI=your_mongodb_connection_string
JWT_SECRET=your_jwt_secret
CLOUDINARY_CLOUD_NAME=your_cloud_name
CLOUDINARY_API_KEY=your_api_key
CLOUDINARY_API_SECRET=your_api_secretcd ../frontend
cp .env.example .envThe default values work for local development out of the box:
VITE_API_BASE_URL=http://localhost:5001/api
VITE_SOCKET_URL=http://localhost:5001# Backend
cd backend && npm install
# Frontend
cd ../frontend && npm install# Terminal 1 — backend
cd backend && npm run dev
# Terminal 2 — frontend
cd frontend && npm run devThe app will be available at http://localhost:5173.
pulse/
├── backend/
│ ├── src/
│ │ ├── controllers/ # Route handlers
│ │ ├── lib/ # DB, Cloudinary, Socket, JWT utils
│ │ ├── middleware/ # Auth middleware
│ │ ├── models/ # Mongoose schemas
│ │ └── routes/ # Express routers
│ ├── .env.example
│ └── package.json
├── frontend/
│ ├── src/
│ │ ├── components/ # Reusable UI components
│ │ ├── pages/ # Route-level page components
│ │ ├── store/ # Zustand state stores
│ │ └── lib/ # Axios instance, utilities
│ ├── .env.example
│ └── package.json
└── assets/
└── img/ # Screenshots
- Passwords hashed with bcryptjs
- Sessions use HTTP-only, SameSite=Strict JWT cookies
- JWT algorithm pinned to HS256 to prevent confusion attacks
- Image uploads validated as base64 data URIs before reaching Cloudinary (SSRF protection)
- Auth routes rate-limited to 10 requests per 15 minutes per IP
- HTTP security headers via helmet
- Client-side file size enforced at 5 MB before any upload
- Core Chat functionality (Text & Image Attachments).
- Authentication System (JWT, Registration).
- Responsive Theme Ecosystem (32 DaisyUI themes).
- Live User States: Real-time visibility tracking (Online/Offline).
- "Last Seen" Tracker: Web-socket powered exact disconnect timestamps.
- Dynamic Typing Indicators: Live-debounced keystroke status relays.
- Message Editing: Modify sent messages with an
(edited)live sync. - Read Receipts (Message Status): 3-tier checking system (
Sent,Delivered,Read). - Sidebar Unread Counters: Displaying numeric red badges
(3)next to offline alerts. - Delete Messages: Local and global database message deletion endpoints.
- Reply Targeting: Anchor a reply contextually to a specific previous message.
- Push Notifications: Native OS notifications for backgrounded browser tabs.
- Message Pagination / Infinite Scroll: Fetching older messages incrementally to save resources.
- Emoji Reactions: Interactive bubble reactions.
- Group Chats: Expanding the underlying schema to support multi-user threads.
Future Ideas
- Link Previews: Auto-generate title and thumbnail cards for pasted URLs.
- Message Pinning: Pin important messages to the top of a conversation.
- Media Gallery: A scrollable grid of all images shared in a conversation.
- Message Forwarding: Forward a message to another contact.
- User Blocking: Prevent specific users from sending messages.
- Contact Requests: Send and accept contact requests instead of seeing every registered user.
- Two-Factor Authentication (2FA): TOTP-based second factor on login.
- File Sharing: Send PDFs and documents in addition to images.
- Status / Stories: 24-hour disappearing status updates.
- Voice / Video Calls: WebRTC-based real-time calls.




