A full-featured Next.js (App Router) e-commerce storefront I built to deepen my understanding of full-stack development. It covers product management, user authentication, favorites & reviews, a shopping cart, Stripe checkout, image uploads (Supabase), and a Postgres + Prisma backend.
- What is this project
- Key features
- ScreenShots
- Tech stack (high level)
- Quickstart β run locally
- Environment variables
- .env.example
- Database & seeding
- How itβs organised (high level)
- How it works (architecture notes)
- Important implementation notes & gotchas
- Scripts
- Deployment notes
- Contributing
- License
A full-stack Next.js storefront I built using the App Router. The goal was to learn how all the pieces of a modern e-commerce app fit together β server-side database operations (Prisma), server actions, user auth (Clerk), image storage (Supabase), and Stripe-powered checkout.
I focused on writing clean, production-style code while exploring how App Router + Prisma + auth + payments can work together in a real Next.js app.
- Product catalog (list, single product pages)
- Admin CRUD for products (image upload + management)
- Favorites (per-user)
- Reviews (per-user, rating + comment)
- Shopping cart persisted in the database per user
- Checkout using Stripe (embedded checkout + server-side session creation)
- Image storage and retrieval via Supabase storage
- Authentication & user state via Clerk
- Uses Prisma to model Product / Favorite / Review / Cart / CartItem / Order
- UI built with shadcn-like components, Radix primitives and TailwindCSS
Single product view with images, price, details, reviews, and Add to Cart.
Displays all products marked as favorites by the user.
User's shopping cart with items, quantity controls, and total price.
Stripe Embedded Checkout used for processing payments.
Admin panel for managing products (create, edit, delete).
- Next.js (App Router)
- React 18 (server + client components)
- Prisma + PostgreSQL (database)
- Clerk for authentication
- Supabase for image storage
- Stripe for payments
- Tailwind CSS + shadcn/Radix UI for UI components
- TypeScript
See
package.jsonfor the exact package list used in this project.
Prerequisites
- Node.js (recommended: latest LTS β Node 18+ / 20+ works with the packages used)
- A Postgres instance (local or managed)
- (Optional) Supabase project for image upload
- Clerk account (for auth) and Stripe account for payments
Steps:
- Clone the repo
git clone https://github.com/GodSonIsBack/Next_Store.git
cd Next_Store- Install dependencies
npm install-
Create a
.env.localat the project root and add the environment variables (see next section) -
Initialize the database and Prisma client
# generate client and push schema to DB
npx prisma generate
npx prisma db push
# optionally run migrations instead of db push if you prefer
# npx prisma migrate dev --name init- Seed example products (the project includes
prisma/products.jsonand aprisma/seed.jshelper)
node prisma/seed.js
# verify with prisma studio if you want
npx prisma studio- Run the dev server
npm run devThe project expects (at minimum) these variables to be defined in your environment (example names used in the project code):
DATABASE_URLβ Postgres connection string (Prisma)DIRECT_URLβ optional direct DB URL used by Prisma if you use pgBouncer or Supabase DirectURL patternsSUPABASE_URLβ your Supabase project URL (used for image storage)SUPABASE_KEYβ key used to access Supabase storage from the server (keep secret)STRIPE_SECRET_KEYβ your Stripe secret key (server)NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEYβ Stripe publishable key (client)ADMIN_USER_IDβ Clerk user id to mark admin operations (used in server actions)- Clerk environment variables β configure Clerk per their docs (dashboard) so that auth works in Next.js (set values in your environment as required by Clerk)
Important: Do NOT commit .env.local to source control. Add it to .gitignore.
# Database
DATABASE_URL=postgresql://USER:PASSWORD@HOST:PORT/DATABASE
DIRECT_URL=postgresql://USER:PASSWORD@HOST:PORT/DATABASE
# Supabase (for image storage)
SUPABASE_URL=https://your-supabase-instance.supabase.co
SUPABASE_KEY=your-service-role-key
# Stripe (payments)
STRIPE_SECRET_KEY=sk_test_...
NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY=pk_test_...
# Clerk (authentication)
NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY=your-clerk-publishable-key
CLERK_SECRET_KEY=your-clerk-secret-key
# App settings
ADMIN_USER_ID=your-clerk-user-id-for-adminUse this template to create .env.local in your project root. Replace placeholders with your actual values.
- Prisma schema is in
prisma/schema.prismaand models:Product,Favorite,Review,Cart,CartItem,Order. - To populate example data the project includes
prisma/products.jsonandprisma/seed.jsβ runnode prisma/seed.jsafternpx prisma db push.
app/ # Next.js App Router pages (server and client components)
components/ # Re-usable UI and feature components
prisma/ # Prisma schema, seed and example products.json
utils/ # DB helper, supabase helper, server actions, zod schemas
public/ # static assets
styles/ # tailwind / global css
Key utilities worth scanning:
utils/actions.tsβ server actions that drive the core product/cart/favorite/review flowsutils/db.tsβ Prisma client singleton pattern (prevents connection explosion in dev)utils/supabase.tsβ image upload / delete helpers (bucket name configured in code)prisma/schema.prismaβ database models
- The project uses Next.js App Router β top-level
app/layout.tsxdefines theClerkProvider+Providersand common layout. - Data fetching and mutations are implemented as server actions and server-side helpers (see
utils/actions.ts) β most actions run on the server and use the Prisma client directly. - Auth is provided by Clerk. Server-side functions call Clerk server helpers (e.g.
currentUser()/auth()) for user context and authorization checks. - Images are uploaded to Supabase Storage via
utils/supabase.tsand public URLs are returned/stored on the product record. - Checkout uses Stripe: the client requests a server-created checkout session (
/api/payment) and then receives aclientSecretfor the embedded checkout flow. After checkout completes the/api/confirmroute marks the orderisPaidand cleans up the cart. - Cart and order totals are computed & stored in the DB via
utils/actionshelper functions.
-
Prisma in dev: the repo uses a Prisma client singleton pattern (
utils/db.ts) to avoid opening many DB connections during Hot Module Replacement (HMR). Keep that in place for local dev to prevent connection exhaustion. -
Image storage bucket: the code expects a bucket name (the example uses
main-bucketinutils/supabase.ts). Either create that bucket in Supabase or change the constant there. -
Admin checks: admin routes/actions compare the current Clerk user id to
ADMIN_USER_ID. Set that env var to one of your test Clerk account ids to allow admin actions. -
Next.js remote images:
next.config.mjscontainsremotePatternsforimages.pexels.com, Supabase hosts, and Clerk images β keep these hosts innext.config.mjsif you add other image sources. -
Build script runs Prisma generate: the
buildscript runsnpx prisma generate && next buildso ensure your DB/Prisma generator config is valid in CI and when deploying.
Common commands (mirror what is in package.json):
npm run dev # starts dev server (next dev)
npm run build # generates Prisma client and builds the app (npx prisma generate && next build)
npm run start # run production server (next start)
npm run lint # run lint checks (if configured)-
Vercel is a natural fit for App Router apps. When deploying:
- Set all environment variables in your Vercel project (DATABASE_URL, DIRECT_URL, SUPABASE_URL, SUPABASE_KEY, STRIPE keys, Clerk keys, ADMIN_USER_ID, etc.)
- Ensure your production DB is accessible from the deployment.
- The
buildstep will runnpx prisma generateβ make sure Prisma has access to the schema generator and network.
-
If you host on other platforms, ensure environment variables and any storage (Supabase) are reachable from your server.
Feel free to fork this repo and build on it. If you want to contribute:
- Keep sensitive values out of the repo (
.env.local) - Seed and test with sample products before adding production data
- Open PRs with small focused changes
MIT β feel free to use this project for your own learning or as a starting point.





