iMessage WebChat is a real-time one-to-one chat application inspired by the iMessage experience. It combines Clerk authentication, MongoDB persistence, Socket.IO realtime events, ImageKit media uploads, and Web Push notifications into a responsive chat app for desktop and mobile.
The app supports live messaging, replies, editing and deleting sent messages, typing indicators, online presence, read receipts, delivery ticks, mobile push notifications, media sharing, theme presets, light/dark mode, wallpapers, and mobile keyboard-friendly layouts.
- 👥One-to-one private conversations
- ⏱️Instant Socket.IO message delivery
- 💾Message history stored in MongoDB
- ↪️Inline replies with jump-to-replied-message support
- ✏️Edit your own sent messages
- 🗑️Delete your own sent messages
- ⚡Cached message loading for faster repeat opens
- 📱Mobile-friendly composer that keeps the keyboard stable while sending
- ✖️Single tick for messages sent to the server
- ✔️Double tick for messages delivered while the receiver is online
- 🔵Colored double tick for messages read by the receiver
- 💬Message status shown inside chat bubbles
- ⏱️Last sent message status shown in the conversation sidebar
- 🔢Unread message counts in the sidebar
- 🟢Online/offline indicators
- ⏳Last seen text for offline users
- ✍️Realtime typing indicator in the active conversation
- 📊Realtime typing indicator in the sidebar
- 🔍Active user tracking through Socket.IO
- 📱Browser and PWA push notifications for new messages
- 🔑Web Push support with VAPID keys
- 🖼️Notification title, sender profile image, message preview, badge, and app icon
- ⚙️Service worker notification click handling
- 🗄️Push subscription storage per user
- 🖼️Image upload support
- 🎥Video upload support
- ☁️ImageKit storage and optimized delivery
- 📝Media captions
- 👁️Image/video previews before sending
- ☀️Light and dark mode
- 🎨Theme preset picker
- ⚙️Accent color customization
- 🖼️Wallpaper picker
- 💾Persistent appearance settings
- 💻Mobile and desktop responsive layouts
- 🔐Clerk authentication
- 🔄Clerk webhook user sync
- 🛡️Protected backend routes
- 🔑Secure session-based API access
- 👤Per-user authorization for editing and deleting messages
- Library: React 19
- Build Tool: Vite
- Styling: Tailwind CSS 4 & HeroUI
- Authentication: Clerk React
- State Management: Zustand
- Routing: React Router 7
- Realtime: Socket.IO Client
- HTTP Client: Axios
- Feedback: React Hot Toast
- Icons: Lucide React
- Framework: Express.js
- Database: MongoDB & Mongoose ORM
- Authentication: Clerk Express
- Realtime: Socket.IO
- Notifications: Web Push
- File Uploads: ImageKit & Multer
- Utilities: Cron, CORS, Dotenv
imessage/
|-- backend/
| |-- src/
| | |-- controllers/
| | |-- lib/
| | |-- middleware/
| | |-- models/
| | |-- routes/
| | |-- seeds/
| | |-- webhooks/
| | `-- index.js
| `-- package.json
|-- frontend/
| |-- public/
| | |-- manifest.webmanifest
| | |-- sw.js
| | `-- notification-badge.png
| |-- src/
| | |-- components/
| | |-- context/
| | |-- data/
| | |-- hooks/
| | |-- lib/
| | |-- pages/
| | `-- store/
| `-- package.json
|-- Dockerfile
`-- README.md
- Node.js 18+
- MongoDB Atlas or local MongoDB
- Clerk account
- ImageKit account for media uploads
- VAPID keys for push notifications
git clone https://github.com/asifcuber08/iMessage-WebChat.git
cd iMessage-WebChatcd backend
npm installCreate backend/.env:
PORT=3000
NODE_ENV=development
MONGO_URI=your_mongodb_connection_string
FRONTEND_URL=http://localhost:5173
CLERK_PUBLISHABLE_KEY=your_clerk_publishable_key
CLERK_SECRET_KEY=your_clerk_secret_key
CLERK_WEBHOOK_SIGNING_SECRET=your_clerk_webhook_signing_secret
IMAGEKIT_PRIVATE_KEY=your_imagekit_private_key
VAPID_PUBLIC_KEY=your_vapid_public_key
VAPID_PRIVATE_KEY=your_vapid_private_key
VAPID_SUBJECT=mailto:you@example.comRun backend:
npm run devcd frontend
npm installCreate frontend/.env:
VITE_CLERK_PUBLISHABLE_KEY=your_clerk_publishable_key
VITE_VAPID_PUBLIC_KEY=your_vapid_public_keyRun frontend:
npm run devcd backend
npm run db:seedThis adds demo users for testing conversations and UI states.
The app uses the Web Push API for mobile/browser notifications. Generate a VAPID key pair and place the public key in both frontend and backend env files.
You can generate keys with:
npx web-push generate-vapid-keysUse the values like this:
# backend/.env
VAPID_PUBLIC_KEY=your_vapid_public_key
VAPID_PRIVATE_KEY=your_vapid_private_key
VAPID_SUBJECT=mailto:you@example.com
# frontend/.env
VITE_VAPID_PUBLIC_KEY=your_vapid_public_key💡Notes:
VAPID_SUBJECTshould be a validmailto:address or URL.FRONTEND_URLshould match your deployed frontend origin in production.- Push notifications require HTTPS in production.
- Users must grant notification permission before subscriptions are saved.
- Installed PWAs may need a refresh or reinstall after icon, manifest, or service worker changes.
Clerk webhooks keep MongoDB users synchronized with Clerk users.
Create a webhook in:
Clerk Dashboard -> Webhooks -> Add Endpoint
🌐Production endpoint:
https://your-domain.com/api/webhooks/clerk
💻Local endpoint:
http://localhost:3000/api/webhooks/clerk
✅Enable these events:
user.created
user.updated
user.deleted
Copy the webhook signing secret into:
CLERK_WEBHOOK_SIGNING_SECRET=your_clerk_webhook_signing_secretImageKit is used for chat media uploads. Add your private key to the backend:
IMAGEKIT_PRIVATE_KEY=your_imagekit_private_keyThe app uploads media through the backend and stores the returned ImageKit URLs on each message.
npm run dev
npm run start
npm run build
npm run db:seednpm run dev
npm run build
npm run preview
npm run lint- 👤User signs in or signs up through Clerk.
- 🔄Clerk webhook syncs the user into MongoDB.
- 🌐The frontend checks auth state through Clerk.
- 🛡️The backend protects API routes with Clerk middleware.
- 📡Socket.IO connects using the MongoDB user id.
- 💬Realtime chat, presence, typing, receipts, and notifications become available.
- 📥
newMessage: sends new messages instantly to online receivers. - ✏️
messageEdited: updates edited messages for both chat participants. - 🗑️
messageDeleted: removes deleted messages for both chat participants. - 🔵
messagesRead: updates read receipts and colored double ticks. - ✍️
userTyping: updates typing state in the chat header and sidebar. - 🟢
getOnlineUsers: keeps online indicators current.
- ⚙️Set
NODE_ENV=productionfor production backend deployments. - 🌐Set
FRONTEND_URLto the exact deployed frontend origin. - 🔑Keep backend and frontend VAPID public keys identical.
- 🔒Configure Clerk production keys and webhook endpoint.
- 🛡️Use HTTPS for push notifications.
- 🔄Restart the backend after schema, socket, or environment changes.
Pull requests are welcome. If you find a bug or want to add a feature, open an issue or submit a PR.
Made by Asif Shamim.