A full-stack MERN e-commerce application with GraphQL, JWT authentication, Stripe payments, and Progressive Web App (PWA) support.
- Overview
- Features
- Tech Stack
- Project Structure
- Getting Started
- Environment Variables
- Available Scripts
- GraphQL API
- Deployment
- Contributing
- License
Shop-Shop is a production-ready e-commerce template built with the MERN stack. It uses Apollo Server 4 for the GraphQL API, React 18 with lazy-loaded routes for the frontend, IndexedDB for offline cart persistence, and Stripe for payment processing.
- Product catalogue — browse products filtered by category
- Shopping cart — add/remove items, update quantities, persisted offline via IndexedDB
- User authentication — register and log in with JWT; passwords hashed with bcrypt
- Checkout — Stripe-hosted checkout session; order history saved per user
- PWA — installable, works offline with a Workbox-powered service worker
- GraphQL API — single
/graphqlendpoint for all queries and mutations - Responsive design — mobile-first CSS with a sticky header and adaptive layout
| Layer | Technology |
|---|---|
| Frontend | React 18, React Router 6, Apollo Client 3, Vite 6 |
| Backend | Node.js, Express 4, Apollo Server 4 |
| Database | MongoDB with Mongoose 8 |
| Auth | JSON Web Tokens (jsonwebtoken 9), bcrypt 5 |
| Payments | Stripe |
| Testing | Vitest, Testing Library, happy-dom |
| PWA | vite-plugin-pwa (Workbox) |
e-commerce-site/
├── client/ # React frontend (Vite)
│ ├── public/ # Static assets (favicon, manifest.json)
│ ├── src/
│ │ ├── assets/ # Images, spinner gif
│ │ ├── components/ # Reusable UI components
│ │ │ ├── Cart/ # Cart drawer + Stripe checkout
│ │ │ ├── CartItem/ # Individual cart row
│ │ │ ├── CategoryMenu/ # Category filter buttons
│ │ │ ├── Jumbotron/ # Hero banner wrapper
│ │ │ ├── Loading/ # Suspense fallback spinner
│ │ │ ├── Nav/ # Sticky navigation header
│ │ │ ├── ProductItem/ # Product card
│ │ │ └── ProductList/ # Grid of ProductItem cards
│ │ ├── pages/ # Lazy-loaded route pages
│ │ │ ├── Detail.jsx # Single product view
│ │ │ ├── Home.jsx # Landing page
│ │ │ ├── Login.jsx # Login form
│ │ │ ├── NoMatch.jsx # 404 page
│ │ │ ├── OrderHistory.jsx
│ │ │ ├── Signup.jsx # Registration form
│ │ │ └── Success.jsx # Post-checkout confirmation
│ │ └── utils/
│ │ ├── actions.js # Redux-style action type constants
│ │ ├── auth.js # AuthService class (JWT helpers)
│ │ ├── GlobalState.jsx # Context + useReducer store
│ │ ├── helpers.js # pluralize() + idbPromise()
│ │ ├── mutations.js # Apollo GraphQL mutations
│ │ ├── queries.js # Apollo GraphQL queries
│ │ └── reducers.js # Pure state reducer
│ └── vite.config.js
├── server/
│ ├── config/
│ │ ├── cleanDB.js # Drops collections before seeding
│ │ ├── connection.js # Mongoose connection
│ │ └── seeds.js # Sample data seed script
│ ├── models/
│ │ ├── Category.js
│ │ ├── Order.js
│ │ ├── Product.js
│ │ ├── User.js
│ │ └── index.js
│ ├── schemas/
│ │ ├── index.js
│ │ ├── resolvers.js # GraphQL resolver functions
│ │ └── typeDefs.js # GraphQL type definitions
│ ├── utils/
│ │ └── auth.js # JWT middleware + signToken
│ └── server.js # Express + Apollo Server entry point
├── .env.example # Template for required environment variables
├── package.json # Root workspace scripts
└── README.md
- Node.js v18 or higher (v22 LTS recommended)
- npm v9+
- MongoDB v6+ running locally, or a free MongoDB Atlas cluster
git clone https://github.com/fredm23579/e-commerce-site.git
cd e-commerce-sitecp .env.example .envOpen .env and fill in the required values — see Environment Variables for details.
npm run installThis installs packages for both the server/ and client/ directories.
npm run seedDrops and recreates sample categories, products, and two test users.
npm run develop| URL | Description |
|---|---|
http://localhost:3000 |
Vite dev server (React frontend with hot reload) |
http://localhost:3001/graphql |
Apollo GraphQL sandbox |
Copy .env.example to .env and set the following:
| Variable | Required | Description |
|---|---|---|
MONGODB_URI |
No | MongoDB connection string. Defaults to mongodb://127.0.0.1:27017/mern-shopping |
JWT_SECRET |
Yes | Long random string used to sign JWT tokens |
STRIPE_SECRET_KEY |
Yes | Stripe secret key — obtain from your Stripe dashboard |
PORT |
No | Server port. Defaults to 3001 |
VITE_STRIPE_PUBLIC_KEY |
Yes | Stripe publishable key (safe to expose in browser) |
Security note: Never commit your
.envfile or real API keys to version control. The.env.examplefile contains only placeholder values and is safe to commit.
Run from the project root:
| Script | Description |
|---|---|
npm run develop |
Start both the Vite dev server and Express server concurrently |
npm start |
Start the production Express server |
npm run build |
Build the React client for production |
npm run preview |
Preview the production build locally |
npm run seed |
Seed the database with sample data |
npm run install |
Install dependencies for both client and server |
The API is available at /graphql. Use the Apollo Sandbox at http://localhost:3001/graphql during development.
| Query | Auth required | Description |
|---|---|---|
categories |
No | All product categories |
products(category, name) |
No | Products with optional filters |
product(_id!) |
No | Single product |
user |
Yes | Current user profile + order history |
order(_id!) |
Yes | Single order by ID |
checkout(products) |
No | Create Stripe checkout session |
| Mutation | Auth required | Description |
|---|---|---|
addUser(...) |
No | Register a new user; returns a JWT |
login(email, password) |
No | Authenticate; returns a JWT |
updateUser(...) |
Yes | Update profile fields |
addOrder(products) |
Yes | Save a completed order |
updateProduct(_id, quantity) |
No | Decrement product stock |
- Create a Web Service connected to your GitHub repository.
- Set Build command:
npm run build - Set Start command:
npm start - Add all environment variables from
.env.examplein the Render dashboard. - Set
NODE_ENV=production.
heroku create your-app-name
heroku config:set JWT_SECRET=... STRIPE_SECRET_KEY=... VITE_STRIPE_PUBLIC_KEY=... MONGODB_URI=...
git push heroku main- Fork the repository and create a feature branch (
git checkout -b feat/your-feature). - Commit your changes with a descriptive message.
- Open a pull request — all PRs are reviewed before merging.
Distributed under the MIT License. © 2024 Fred Motta Ortiz.