A production-minded MERN e-commerce app showcasing end-to-end shopping flows (auth, cart, orders, and admin product management) with a deployable setup and CI-backed quality checks.
- Frontend (Vercel): https://fullstack-eshop.vercel.app
- Backend (Render API Base): https://fullstack-eshop.onrender.com/api
- Backend health: https://fullstack-eshop.onrender.com/health
- Backend readiness: https://fullstack-eshop.onrender.com/ready
- Full authentication-to-order flow with protected user/admin routes and JWT-based access control.
- Clean monorepo split (
client/+server/) ready for independent cloud deployment. - Production health endpoints (
/health,/ready) for uptime checks and platform probes. - CI coverage for server lint/tests plus client lint/tests/build on every PR.
- JWT authentication with protected user and admin routes.
- Product catalog browsing with category and search support.
- Cart and checkout-ready order workflow.
- Admin-only product management endpoints for create/update/delete.
- Responsive React UI with reusable components and route-based pages.
- CI pipeline validating server lint/tests and client lint/tests/build on pull requests.
| Layer | Stack |
|---|---|
| Client | React, React Router, Vite, ESLint |
| Server | Node.js, Express, Mongoose |
| DB | MongoDB Atlas (or compatible MongoDB deployment) |
| Auth | JWT + bcrypt password hashing |
| CI | GitHub Actions (.github/workflows/ci.yml) |
This repository is organized as a simple two-app monorepo:
client/: React SPA (pages, components, context, API service helpers)server/: Express API (routes, controllers, models, middleware, seeding)docs/: project architecture and screenshot guidance
For a quick diagram and request flow, see docs/ARCHITECTURE.md.
git clone https://github.com/ardidrizi/fullstack-eshop.git
cd fullstack-eshop
npm --prefix server install
npm --prefix client installcp server/.env.example server/.env
cp client/.env.example client/.env# terminal 1
npm --prefix server run dev
# terminal 2
npm --prefix client run dev- Client runs on
http://localhost:5173 - API runs on
http://localhost:3000
PORT: API server port (default3000).MONGO_URI: MongoDB connection string. Create from MongoDB Atlas Database > Connect > Drivers.MONGO_URL(optional): backward-compatible alias for older local configs.JWT_SECRET: random secret used to sign auth tokens (openssl rand -base64 32works well).FRONTEND_URL: Vercel frontend origin allowed by backend CORS (for examplehttps://<vercel-app>.vercel.app).
After updating backend environment variables (including
FRONTEND_URL), redeploy/restart the backend so the new values are applied.
VITE_API_URL: base API URL consumed by client (http://localhost:3000/apilocally). For Vercel + Render setVITE_API_URL=https://<render-service>.onrender.com/api.
Use the following project settings:
Root Directory: client
Build Command: npm run build
Output Directory: distSet this environment variable in Vercel:
VITE_API_URL=https://fullstack-eshop.onrender.com/apiVite only exposes
VITE_*variables to the client bundle, and these variables are injected at build time.
Set these Render environment variables:
MONGO_URI=...
JWT_SECRET=...
FRONTEND_URL=https://fullstack-eshop.vercel.appFRONTEND_URL must be the exact frontend origin with no trailing slash.
The seeding workflow reads
MONGO_URIfirst and falls back toMONGO_URLfor backward compatibility.
The API includes a production-safe seed workflow that inserts missing records by unique key (idempotent by default). Product images are sourced from curated per-category image pools so seeded catalogs stay visually realistic and category-consistent.
# optional first run
cp server/.env.example server/.env
# seeds categories, products, demo users, and demo orders
npm --prefix server run seed
# optional: clear only demo seed records first (only when you explicitly want a reset)
npm --prefix server run seed:clear
# optional: customize data volume and demo credentials
SEED_COUNT_PRODUCTS=48 DEMO_ADMIN_EMAIL=owner@eshop.dev DEMO_ADMIN_PASSWORD='StrongAdmin123!' npm --prefix server run seedRun the same script either from your machine (pointing at Atlas) or from Render Shell:
# from local machine against Atlas
MONGO_URI='mongodb+srv://<user>:<pass>@<cluster>/<db>?retryWrites=true&w=majority' npm --prefix server run seed
# if you intentionally need to rebuild seed data
MONGO_URI='mongodb+srv://<user>:<pass>@<cluster>/<db>?retryWrites=true&w=majority' npm --prefix server run seed:clearRender Shell example:
cd /opt/render/project/src
npm --prefix server run seedEnvironment flags used by the seed script:
SEED_CLEAR=true: allow deleting existing demo seed records before inserting.SEED_COUNT_PRODUCTS=40: optional minimum product count.DEMO_ADMIN_EMAIL,DEMO_ADMIN_PASSWORD: admin demo credentials.DEMO_USER_EMAIL,DEMO_USER_PASSWORD: primary demo customer credentials.DEMO_USER_TWO_EMAIL,DEMO_USER_TWO_PASSWORD: optional secondary demo customer credentials.
The API exposes lightweight operational endpoints suitable for Render (and similar PaaS health probes):
GET /healthreturns200with process-level metadata and does not require auth or database access.GET /readyreturns:200whenmongoose.connection.readyState === 1(connected)503otherwise
Example:
curl -i http://localhost:3000/health
curl -i http://localhost:3000/readyNote: Render free-tier services may cold start after inactivity, so first probe latency can be higher.
- Confirm
VITE_API_URLincludes/api:- ✅
https://fullstack-eshop.onrender.com/api - ❌
https://fullstack-eshop.onrender.com
- ✅
- Confirm
FRONTEND_URLmatches the exact frontend origin and has no trailing slash:- ✅ Correct:
https://fullstack-eshop.vercel.app - ❌ Incorrect:
https://fullstack-eshop.vercel.app/
- ✅ Correct:
- Confirm health endpoint returns
200JSON:curl -i https://fullstack-eshop.onrender.com/health
- Confirm API 404 handler returns JSON (not HTML):
curl -i https://fullstack-eshop.onrender.com/api/does-not-exist
If browser requests fail but curl works, re-check backend CORS config (FRONTEND_URL) and redeploy Render.
- Screenshot guidance and placeholders:
docs/SCREENSHOTS.md - Place image files under
docs/screenshots/
# server API tests + server syntax lint
npm --prefix server run lint
npm --prefix server test
# client lint + smoke test + production build
npm --prefix client run lint
npm --prefix client test
npm --prefix client run buildGitHub Actions workflow (.github/workflows/ci.yml) runs on every pull request and performs:
- Server job: install, lint, API tests
- Client job: install, lint, smoke test, build
- Add end-to-end checkout coverage (browser-level tests).
- Add API OpenAPI/Swagger documentation.
- Improve order lifecycle (paid/shipped statuses + events).
- Add richer observability (structured logs and health checks).
- Introduce role-based admin dashboard analytics.
- Backend API tests currently mock model persistence to keep CI fast and deterministic.
- Frontend test scope is a smoke-level server-render check, not full browser interaction coverage.
- Client API URL configuration now uses a single source of truth (
VITE_API_URL) to reduce deployment misconfiguration risk. - Architecture remains intentionally simple (monorepo with two apps) over heavier workspace tooling.

