A full-stack, real-time chat application built with the MERN stack and Socket.IO. Users can sign up, chat one-to-one in real time, share images, and personalize the app with multiple themes. The frontend is deployed on Vercel and the backend on Render.
- JWT authentication — Signup, login, and logout backed by JSON Web Tokens stored in secure http-only cookies, so the token is never exposed to client-side JavaScript.
- Real-time messaging — One-to-one conversations delivered instantly over a Socket.IO connection, with new messages appearing without a page refresh.
- Online presence — See at a glance which users are currently online; presence updates live as people connect and disconnect.
- Typing indicator — Know when the person you're chatting with is typing a reply.
- Image sharing — Send images in a conversation; uploads are stored and served through Cloudinary.
- Delete messages — Remove a message for yourself (hidden only from your view) or for everyone (removed from both sides of the conversation in real time).
- Profile management — Update your profile picture at any time.
- Themes — Switch between multiple built-in UI themes powered by DaisyUI.
| Layer | Technologies |
|---|---|
| Frontend | React, Vite, Tailwind CSS, DaisyUI, Zustand, Axios, Socket.IO client |
| Backend | Node.js, Express, Socket.IO, Mongoose |
| Database | MongoDB |
| Auth | JWT, bcrypt |
| Media | Cloudinary |
| Deployment | Vercel (frontend), Render (backend) |
Chat-app-tutorial/
├── backend/
│ └── src/
│ ├── controllers/ # Route handlers (auth, messages)
│ ├── lib/ # DB, Socket.IO, Cloudinary, utils
│ ├── middleware/ # Auth guard for protected routes
│ ├── models/ # Mongoose schemas (User, Message)
│ ├── routes/ # Express routers
│ ├── seeds/ # Sample user seeding script
│ └── index.js # App entry point
└── frontend/
└── src/
├── components/ # UI components (chat, sidebar, navbar, ...)
├── constants/ # Static data (themes, etc.)
├── lib/ # Axios instance, helpers
├── pages/ # Home, Login, Signup, Profile, Settings
├── store/ # Zustand stores (auth, chat, theme)
└── App.jsx
- Node.js 18+
- A MongoDB database — a free MongoDB Atlas cluster works well.
- A Cloudinary account — for storing uploaded images.
git clone https://github.com/iampratik13/Chat-app-tutorial.git
cd Chat-app-tutorialFrom the project root you can install both apps at once:
npm run install:allOr install each app individually:
npm install --prefix backend
npm install --prefix frontendcd backend
cp .env.example .envFill in backend/.env:
| Variable | Description |
|---|---|
PORT |
Port the API runs on (e.g. 5001) |
NODE_ENV |
development locally, production when deployed |
CLIENT_URL |
Frontend origin (e.g. http://localhost:5173) |
MONGODB_URI |
MongoDB connection string |
JWT_SECRET |
Secret used to sign JWTs |
CLOUDINARY_CLOUD_NAME |
Cloudinary cloud name |
CLOUDINARY_API_KEY |
Cloudinary API key |
CLOUDINARY_API_SECRET |
Cloudinary API secret |
cd frontend
cp .env.example .envSet the API base URL in frontend/.env:
VITE_API_BASE_URL=http://localhost:5001Start the backend and frontend in two separate terminals:
# Terminal 1 — API on http://localhost:5001
npm run dev:backend
# Terminal 2 — app on http://localhost:5173
npm run dev:frontendThen open http://localhost:5173 in your browser.
Run these from the project root:
| Script | Description |
|---|---|
npm run install:all |
Install dependencies for backend + frontend |
npm run dev:backend |
Start the backend in watch mode (nodemon) |
npm run dev:frontend |
Start the Vite dev server |
npm run build:frontend |
Build the frontend for production |
npm run start:backend |
Start the backend in production mode |
- Root Directory:
backend - Build Command:
npm install - Start Command:
npm start - Environment variables: the same keys as
backend/.env.example, withNODE_ENV=productionandCLIENT_URLset to your deployed Vercel URL.
- Root Directory:
frontend - Framework Preset: Vite
- Environment variable:
VITE_API_BASE_URLset to your deployed Render URL.