Real-time chat application with authentication, user profiles (including profile picture upload), and messaging over WebSockets.
- Authentication (register, login, logout) using JWT in httpOnly cookies
- Auth session check endpoint (
/auth/check) - Profile picture upload (base64 upload -> Cloudinary)
- Real-time messaging with Socket.IO
- Contacts list and chat history
- Basic API protection/rate limiting via Arcjet middleware
- React (Vite)
- Zustand (state management)
- TailwindCSS + daisyUI
- Axios
- Socket.IO Client
- Node.js + Express
- MongoDB + Mongoose
- Socket.IO
- JWT (httpOnly cookie)
- Cloudinary (media uploads)
- Arcjet (rate limiting / protection)
frontend/— React appbackend/— Express + Socket.IO server
- Node.js (LTS recommended)
- MongoDB connection string (MongoDB Atlas or local)
- Cloudinary account (for profile pictures / image messages)
cd backend
npm installcd frontend
npm installCreate .env files in both backend/ and frontend/.
The backend uses these variables (based on the code in backend/server.js, backend/config/db.js, backend/utils/generateToken.js, and backend/config/cloudinary.js):
# Server
PORT=3000
NODE_ENV=development
CLIENT_URL=http://localhost:5173
# Database
MONGODB_URI=mongodb+srv://<user>:<password>@<cluster-host>
# Auth
JWT_SECRET=your_super_secret_jwt_key
# Cloudinary
CLOUDINARY_CLOUD_NAME=your_cloud_name
CLOUDINARY_API_KEY=your_api_key
CLOUDINARY_API_SECRET=your_api_secret
# Email (if configured)
RESEND_API_KEY=your_resend_api_keyNotes:
MONGODB_URIis used like${MONGODB_URI}/iChatinbackend/config/db.js.- Cookies are set as
httpOnlyand will use:secure: trueonly in productionsameSite: "none"in production,"strict"in development
Frontend uses VITE_API_URL for non-development builds (see frontend/src/lib/axios.js).
VITE_API_URL=http://localhost:3000/In development mode, the frontend automatically uses http://localhost:3000/.
cd backend
npm run devBackend starts on http://localhost:3000 by default.
cd frontend
npm run devFrontend starts on http://localhost:5173 by default.
Base URL: http://localhost:3000
POST /auth/registerPOST /auth/loginPOST /auth/logoutGET /auth/check(requires auth cookie)PUT /auth/update-profile(requires auth cookie)
GET /messages/contacts(requires auth cookie)GET /messages/chats(requires auth cookie)GET /messages/:id(requires auth cookie)POST /messages/send/:id(requires auth cookie)
- Socket server is created in
backend/utils/socket.js. - Socket connections are authenticated using the
jwtcookie (backend/middlewares/socketAuth.js).
- Configure
CLIENT_URLto your deployed frontend URL. - Ensure cookies work across domains:
- backend must enable CORS with
credentials: true - cookie
sameSite/securemust match your deployment (HTTPS required forsameSite=none).
- backend must enable CORS with
npm run dev— start server with nodemonnpm start— start server
npm run dev— start Vite dev servernpm run build— production buildnpm run preview— preview production buildnpm run lint— run ESLint