Full‑stack Instagram-like app with posts, follows, bookmarks, comments, real-time chat, and real-time notifications.
- Auth: Register/Login/Logout using JWT stored in an HTTP-only cookie
- Profiles: Edit bio, gender, and profile picture (Cloudinary upload)
- Posts: Create (image), like/dislike, comment, delete
- Social: Follow/unfollow, followers/following lists, suggested users
- Bookmarks: Save/unsave posts
- Realtime: Online users list, message delivery, like/dislike notifications (Socket.IO)
- Frontend: React + Vite, Tailwind CSS, Redux Toolkit, React Router, Axios, Socket.IO client
- Backend: Node.js (ESM), Express, MongoDB/Mongoose, Socket.IO, Multer (memory), Sharp (image optimize), Cloudinary
- Backend:
backend/(server entry:backend/index.js) - Frontend:
frontend/(Vite app)
Create a .env file at the repo root (because the backend is started from the repo root via backend/index.js).
PORT=5000
URL=http://localhost:5173
MONGO_URI=mongodb://127.0.0.1:27017/instagram-clone
JWT_SECRET=replace-with-a-long-random-secret
CLOUDINARY_CLOUD_NAME=your_cloud_name
# NOTE: this key is intentionally spelled like the code expects it:
CLOUDNIARY_API_KEY=your_cloudinary_api_key
CLOUDINARY_API_SECRET=your_cloudinary_api_secretInstall dependencies (run once):
npm install
npm install --prefix frontendStart backend (API + Socket.IO):
npm run devStart frontend (Vite dev server) in a second terminal:
npm run dev --prefix frontend- Frontend: typically
http://localhost:5173 - Backend:
http://localhost:5000(or whatever you set inPORT)
The frontend currently calls a deployed URL (https://instagram-clone-awa2.onrender.com) directly in multiple files (Axios calls + Socket.IO connection). For local development you must update those URLs to your local backend, for example http://localhost:5000.
Files to update include:
frontend/src/App.jsx(Socket.IO connection URL)frontend/src/components/*.jsxandfrontend/src/hooks/*.jsx(Axios API calls)
All routes are mounted under:
- User:
/api/v1/user - Post:
/api/v1/post - Message:
/api/v1/message
User routes:
POST /api/v1/user/registerPOST /api/v1/user/loginGET /api/v1/user/logoutGET /api/v1/user/:id/profilePOST /api/v1/user/profile/edit(multipart form-data:profilePicture)GET /api/v1/user/suggestedPOST /api/v1/user/followorunfollow/:idGET /api/v1/user/allfollowers/:idGET /api/v1/user/allfollowing/:id
Post routes:
POST /api/v1/post/addpost(multipart form-data:image,caption)GET /api/v1/post/allGET /api/v1/post/userpost/allGET /api/v1/post/:id/likeGET /api/v1/post/:id/dislikePOST /api/v1/post/:id/comment(JSON body:text)POST /api/v1/post/:id/comment/allDELETE /api/v1/post/delete/:idGET /api/v1/post/:id/bookmark
Message routes:
POST /api/v1/message/send/:id(JSON body:message)GET /api/v1/message/all/:id
- Client connects with query
userId - Server emits:
getOnlineUsers(array of userIds)newMessage(message payload)notification(like/dislike notification payload)
Build frontend and serve it from the backend:
npm run buildThis produces frontend/dist, and the backend serves it via:
express.static(/frontend/dist)- a catch-all
GET *that returnsfrontend/dist/index.html
Start server:
npm start- CORS / cookies not working: set
URLto your frontend origin (example:http://localhost:5173). Requests use cookies (withCredentials: true) and the backend enablescredentials: truein CORS. - Cloudinary auth errors: confirm your
.envusesCLOUDNIARY_API_KEY(misspelling matchesbackend/utils/cloudinary.js). - Server won’t start: ensure
PORTis set in.env(the code does not provide a default).