Real-time chat application built with React (Vite) on the frontend and Node.js/Express + Socket.IO + MongoDB on the backend. Supports authentication, profile updates (Cloudinary), online users presence, and real-time messaging.
- Authentication with JWT (HTTP-only cookies)
- Real-time messaging via Socket.IO
- Online users presence
- Profile picture upload (Cloudinary)
- React Router navigation
- Global state with Zustand
- TailwindCSS + DaisyUI styling
PingMe/
├─ client/
│ ├─ src/
│ ├─ public/
│ ├─ package.json
│ └─ vite.config.js
├─ server/
│ ├─ src/
│ │ ├─ config/ (database, socket, cloudinary, utils)
│ │ ├─ controllers/ (auth, message)
│ │ ├─ routes/ (auth.route, message.route)
│ │ ├─ models/ (User, Message)
│ │ └─ index.js
│ └─ package.json
└─ .gitignore
- Frontend: React 18, Vite 5, React Router, Zustand, Tailwind + DaisyUI, axios, react-hot-toast, lucide-react
- Backend: Node 18+, Express, Socket.IO, MongoDB (Mongoose), JWT, bcryptjs, Cloudinary
- Node.js 18+ and npm
- MongoDB connection string
- Cloudinary account (for image uploads)
cd serverCreate .env with (example values shown):
PORT=3000
MONGODB_URI=YOUR_MONGODB_URI
JWT_SECRET=YOUR_LONG_SECRET
CLOUDINARY_CLOUD_NAME=...
CLOUDINARY_API_KEY=...
CLOUDINARY_API_SECRET=...
CLIENT_URL=http://localhost:5173
SERVER_URL=http://localhost:3000
CLIENT_URL=http://localhost:5173
Then install and run:
npm ci
npm run devcd clientCreate .env.local for dev:
VITE_API_URL=http://localhost:3000/api
VITE_SOCKET_URL=http://localhost:3000
Then install and run:
npm ci
npm run devApp will run at: http://localhost:5173
PORT(default 3000)MONGODB_URIJWT_SECRETCLOUDINARY_CLOUD_NAME,CLOUDINARY_API_KEY,CLOUDINARY_API_SECRETCLIENT_URL— Comma-separated list of allowed URLs
Example:https://your-frontend-domain.com,http://localhost:5173
Optional:
CLIENT_URL— Single allowed URL if not using multiple.
VITE_API_URL— Full API base with/api, e.g.https://your-backend-domain.com/apiVITE_SOCKET_URL— Socket URL without/api, e.g.https://your-backend-domain.com
Defaults (if not set)
- Dev: axios →
http://localhost:3000/api, socket →http://localhost:3000 - Prod: axios →
/api, socket →/(works when frontend and backend share the same domain)
npm run dev— Vite dev servernpm run build— Production buildnpm run preview— Preview production build locally
npm run dev— Start with nodemonnpm start— Start with node
You can deploy the backend to any WebSocket-friendly host such as Render, Railway, Fly.io, or your own VPS.
- Deploy the
serverfolder. - Set environment variables:
PORT=3000 MONGODB_URI=your_connection_string JWT_SECRET=your_secret CLOUDINARY_CLOUD_NAME=... CLOUDINARY_API_KEY=... CLOUDINARY_API_SECRET=... CLIENT_URL=https://your-frontend-domain.com - Ensure your host allows:
- WebSocket connections
- CORS from your frontend domain(s)
- Deploy the
clientbuild output (dist/) to your chosen static host (e.g., Netlify, GitHub Pages, Firebase Hosting, Cloudflare Pages, etc.). - Set frontend environment variables before building:
VITE_API_URL=https://your-backend-domain.com/api VITE_SOCKET_URL=https://your-backend-domain.com - Build and deploy:
npm run build
Base: /api
Auth
POST /auth/signupPOST /auth/loginPOST /auth/logoutGET /auth/check(protected)PUT /auth/update-profile(protected)
Messages
- Routes under
/messages(protected)
Socket.IO
- Path:
/socket.io - Query:
?userId=<id> - Event:
getOnlineUsers
-
401/403 in production:
EnsureCLIENT_URLorCLIENT_URLincludes your deployed frontend URL. -
Socket not connecting:
Make sureVITE_SOCKET_URLis set correctly, and backend CORS allows your frontend domain. -
404 for
/apiroutes:
ConfirmVITE_API_URLpoints to your backend API base.
This project is provided as-is for learning and demo purposes.