Swiggyβstyle food discovery app β React frontend + Express API with cached menu proxy, JWT auth, and MongoDB favorites.
- Robust Swiggy data proxy: restaurant list + menu via backend with caching and rate limiting.
- Authentication with JWT (signup/login) and protected favorites endpoints.
- MongoDB persistence for Favorites and Recently Viewed (per-device history).
- Modern React UI with Tailwind, skeleton loaders, debounced search, and empty states.
- Configurable coordinates and API base at build time for easy deployments.
Highβlevel overview of the system:
- Technologies: React + React Router + Redux Toolkit, Tailwind CSS, Express + Node, MongoDB, Axios, Helmet, expressβrateβlimit, NodeCache, Parcel bundler.
- Interaction: The frontend calls a Express backend that proxies Swiggy endpoints, adds caching and CORS handling, and stores user data in MongoDB.
- Persistence: MongoDB collections store
users,favorites, andrecentlyVieweditems. - Security: JWT for protected routes, Helmet for headers, CORS control, and basic rate limiting.
ββββββββββββββββββββββββββββββββββββββ ββββββββββββββββββββββββ
β React Frontend β β MongoDB β
β (Parcel build, Tailwind UI) β β users/favorites/RV β
βββββββββββββββββ¬βββββββββββββββββββββ ββββββββββββ¬ββββββββββββ
β HTTPS (API_BASE_URL) β
βΌ β
βββββββββββββββββββββββββββββ β
β Express API ββββββ JWT βββββββββββ
β helmet, cors, rate-limit β
β cache(proxyβSwiggy) β
ββββββββββββ¬βββββββββββββββββ
β
βΌ
Swiggy public API
- Frontend:
react,react-router-dom,react-redux/@reduxjs/toolkit,tailwindcss,parcel - Backend:
express,axios,helmet,compression,cors,express-rate-limit,jsonwebtoken,mongoose,node-cache,morgan,bcryptjs - Language/Runtime:
node >= 18 - Infra/Deploy: Render (see
render.yaml), static frontend indist/
Prerequisites: Node 18+, a MongoDB connection string (local or Atlas).
- Backend
cd backend
npm install
# create .env and set variables (see Configuration)
npm run dev
# Health check
Invoke-WebRequest http://localhost:8080/health | Select-Object -ExpandProperty Content- Frontend
cd .. # project root
npm install
# Start dev server (Parcel)
npm start
# Optionally run with your local backend in dev
$env:API_BASE_URL="http://localhost:8080"; npm start-
Development
- Backend:
cd backend; npm run dev - Frontend: at repo root
npm start
- Backend:
-
Production
- Build frontend with your API base URL:
$env:API_BASE_URL="https://YOUR-BACKEND.onrender.com"; npm run build
- Serve the static
dist/directory (any static host). Backend runs withcd backend; npm start.
- Build frontend with your API base URL:
- Browse restaurants on the home page; search is debounced for responsiveness.
- Click a restaurant to view its menu (fetched via backend proxy).
- Sign up and log in to add/remove favorites (protected via JWT).
- Recently Viewed is tracked per device using a deviceId stored in
localStorage.
Screenshots:
Backend (backend/.env):
PORT=8080 # Render supplies this automatically
NODE_ENV=development # or production
ALLOWED_ORIGIN=* # or https://your-frontend.example
MONGODB_URI=YOUR_MONGODB_URI # required for persistence
MONGODB_DB=foodiehub # optional database name
JWT_SECRET=please-change # required in production
JWT_EXPIRES_IN=7d # token expiry
CACHE_TTL=300 # seconds; cache for proxy endpoints
Frontend (buildβtime env at repo root):
```powershell
$env:API_BASE_URL="http://localhost:8080"; npm start # dev
$env:API_BASE_URL="https://YOUR-BACKEND.onrender.com"; npm run build # prodBase URL is your backend (local http://localhost:8080).
GET /healthβ{ ok: true, uptime }- Auth
POST /api/auth/signupβ{ ok, token, user }POST /api/auth/loginβ{ ok, token, user }GET /api/auth/me(Bearer token) β{ ok, user }
- Swiggy proxy
GET /api/restaurants?lat=..&lng=..β restaurant list JSONGET /api/restaurants/:id?lat=..&lng=..β menu JSON
- Favorites (Bearer token)
GET /api/favoritesβ{ ok, items }POST /api/favorites{ restaurantId, info? }β{ ok, item }DELETE /api/favorites/:restaurantIdβ{ ok: true }
- Recently Viewed (device-scoped)
GET /api/recently-viewed?deviceId=...&limit=20POST /api/recently-viewed{ deviceId, restaurantId, info? }
- Proxy responses are cached inβmemory using
node-cachewithCACHE_TTL(default 300s). express-rate-limitcaps clients at 120 req/min per IP to protect upstream.
.
ββ backend/
β ββ src/
β β ββ lib/ # config, cache, auth, db connection
β β ββ models/ # mongoose models (User, Favorite, RecentlyViewed)
β β ββ routes/ # auth, favorites, recentlyViewed, swiggy, health
β ββ package.json
ββ src/ # React app (components, utils, store)
ββ render.yaml # Render deploy config
ββ index.html, index.css
ββ package.json # frontend build (Parcel) & root scripts
ββ docs/ # screenshots used in this README
JWTauth for protected routes (favorites).helmetfor secure HTTP headers.corswith configurableALLOWED_ORIGIN.express-rate-limitto mitigate abuse of proxy endpoints.- Passwords hashed with
bcryptjs.
Render (recommended)
-
Backend (Web Service)
- Root:
backend/ - Build:
npm install - Start:
npm start - Env:
MONGODB_URI,ALLOWED_ORIGIN,JWT_SECRET,CACHE_TTL(optional).PORTprovided by Render.
- Root:
-
Frontend (Static Site)
- Root: repo root
- Build: set API and build with Parcel
$env:API_BASE_URL="https://YOUR-BACKEND.onrender.com"; npm run build
- Publish directory:
dist/
Live link: https://foodiehub-ua2d.onrender.com/
- Replace inβmemory cache with Redis for multiβinstance deployments.
- Add e2e tests and CI pipeline.
- Add pagination and sorting for lists.
- Add user profile and social signβin (OAuth).
- Add orders/cart backend and payment integration (demo mode).
ISC β see LICENSE.
- Inspired by Swiggyβs public web API structure.
- Logos and badges courtesy of Shields.io and respective projects.


