A production-ready SaaS starter template built with Next.js 16, Whop (for auth and payments), Prisma 7 (PostgreSQL), and Tailwind CSS v4.
Authentication, payments, subscription management, and a clean dashboard — wired up and ready to go.
The fastest way to get started. Click the button, follow the prompts, and you'll have a running app in minutes.
What happens when you click Deploy:
- Vercel clones the repo to your GitHub account
- You're prompted to add a Postgres database (Neon, Supabase, Prisma Postgres, or Nile)
- Vercel builds and deploys — the database tables are created automatically
- Visit your app — the setup wizard walks you through connecting Whop
No environment variables to fill in manually. The setup wizard handles everything.
After deploying, visit your app URL. The setup wizard will appear automatically and guide you through:
- Connect Whop — Enter your App ID and API Key
- Configure OAuth — Copy-paste your redirect URI and webhook URL
- Sign in — Test OAuth and become the admin
- Set up plans — Enter your Whop plan IDs for pricing tiers
The wizard stores all config in your database — no environment variables needed.
If you prefer setting things up via environment variables (or for CI/CD), follow these steps.
git clone https://github.com/whopio/whop-saas-starter.git
cd whop-saas-starter
pnpm installThen copy the environment template:
cp .env.example .env.localYou need a PostgreSQL database to store user accounts, sessions, and app config.
- Create a free database with Neon, Supabase, or Prisma Postgres
- Copy the connection string (starts with
postgresql://...) - Add it as
DATABASE_URLin.env.local(or Vercel Environment Variables if deploying) - Push the database schema:
pnpm db:push
Tip: If you used the Deploy to Vercel button and added a Postgres integration, this is already done —
DATABASE_URLis set automatically and the schema is pushed during build.
- Go to whop.com/dashboard/developer
- Click Create App
- You'll see your app credentials:
- Client ID — looks like
app_xxxxxxxxx - API Key — looks like
apik_xxxxxxxxx
- Client ID — looks like
- Under the OAuth section:
- Set Client mode to Public
- Add your Redirect URI:
https://YOUR-APP.vercel.app/api/auth/callback- (Replace
YOUR-APPwith your actual Vercel domain)
Why Public mode? It uses PKCE (a secure code exchange) instead of a static client secret. This is the recommended approach and what this template is built for.
You need to create plans (pricing tiers) in Whop so users can subscribe.
- Go to whop.com/dashboard
- Create a product for each tier (e.g., Free, Starter, Pro)
- For each product, create a plan with the price you want
- For the Free tier: create a $0 plan (this lets you manage all users in Whop)
- Copy each Plan ID — it looks like
plan_xxxxxxxxx- Find it in the plan's settings or checkout link details
- Important: Use the
plan_ID, not theprod_ID
Where to find Plan IDs: Go to your product → Checkout links → click Details on any pricing option. The Plan ID starts with
plan_.
Add these to .env.local (or your Vercel project's Settings → Environment Variables if deploying):
| Variable | Where to find it | Example |
|---|---|---|
NEXT_PUBLIC_WHOP_APP_ID |
Whop Developer Dashboard → your app | app_xxxxxxxxx |
WHOP_API_KEY |
Whop Developer Dashboard → your app | apik_xxxxxxxxx |
NEXT_PUBLIC_APP_URL |
Your Vercel deployment URL | https://your-app.vercel.app |
DATABASE_URL |
Auto-set if you added Postgres during deploy | postgresql://... |
NEXT_PUBLIC_WHOP_FREE_PLAN_ID |
Whop Dashboard → your Free plan | plan_xxxxxxxxx |
NEXT_PUBLIC_WHOP_STARTER_PLAN_ID |
Whop Dashboard → your Starter monthly plan | plan_xxxxxxxxx |
NEXT_PUBLIC_WHOP_STARTER_PLAN_ID_YEARLY |
Whop Dashboard → your Starter yearly plan | plan_xxxxxxxxx |
NEXT_PUBLIC_WHOP_PRO_PLAN_ID |
Whop Dashboard → your Pro monthly plan | plan_xxxxxxxxx |
NEXT_PUBLIC_WHOP_PRO_PLAN_ID_YEARLY |
Whop Dashboard → your Pro yearly plan | plan_xxxxxxxxx |
SESSION_SECRET |
Optional. Auto-generated and stored in DB if not set | a1b2c3d4... |
Tip: If you added a Postgres database during the Vercel deploy,
DATABASE_URLis already set. Check your Environment Variables to confirm.
About SESSION_SECRET: A secret key used to sign login sessions. You don't need to set this — the app automatically generates one and stores it in your database. If you prefer to manage it yourself, set any random 32+ character string.
After adding the variables, redeploy your app (Vercel → Deployments → click the three dots on the latest deployment → Redeploy).
Webhooks tell your app when someone subscribes, cancels, or gets refunded.
- Go to whop.com/dashboard/developer
- Select your app → Webhooks
- Click Create Webhook
- Set the URL to:
https://YOUR-APP.vercel.app/api/webhooks/whop - Subscribe to these events:
membership_activatedmembership_deactivatedpayment_succeededpayment_failedrefund_createddispute_created
- Copy the Webhook Secret and add it as
WHOP_WEBHOOK_SECRETin your Vercel env vars - Redeploy again after adding the webhook secret
- Visit your app URL
- Click Sign in — you should be redirected to Whop's login page
- After signing in, you should land on the dashboard
- Go to the pricing page and try subscribing to a plan
- Check the Whop dashboard to see the subscription
That's it! Your SaaS is live.
Follow Steps 1–5 above to clone the repo, set up a database, and configure your environment variables in .env.local.
For local webhook testing, use ngrok to expose your local server:
ngrok http 3000Then add the ngrok URL as a webhook endpoint in Whop: https://xxxx.ngrok.io/api/webhooks/whop
Start the dev server:
pnpm devOpen http://localhost:3000.
- Authentication — Sign in with Whop (OAuth 2.1 + PKCE)
- Payments — Subscription billing via embedded Whop checkout
- Webhooks — Automatic plan upgrades/downgrades on subscription changes
- Dashboard — Protected, responsive dashboard with sidebar navigation
- Database — PostgreSQL with Prisma ORM (auto-provisioned on deploy)
- Route protection — Middleware protects
/dashboard/*routes - Landing page — Marketing page with hero, features, and pricing sections
- Dark mode — Automatic dark/light mode based on system preference
- AI-ready — Bundled agent skill guides Claude Code, Cursor, Copilot, and other AI agents on how to extend this template
app/
├── (marketing)/pricing/ # Pricing page
├── (auth)/login/ # Login page
├── dashboard/ # Protected dashboard (layout enforces auth)
├── checkout/ # Embedded Whop checkout
├── checkout/success/ # Post-payment redirect
└── api/
├── auth/login/ # Initiate OAuth
├── auth/callback/ # OAuth callback
├── auth/logout/ # Clear session
├── auth/me/ # Current user (client-side)
└── webhooks/whop/ # Whop webhook handler
components/
├── landing/ # Marketing page components
└── dashboard/ # Dashboard components
db/
├── index.ts # Prisma client singleton
└── schema.prisma # Database schema
lib/
├── auth.ts # Session management (JWT cookies)
├── subscription.ts # Typed subscription/membership query helpers
├── whop.ts # Whop OAuth + webhook helpers
├── constants.ts # Plan tiers (single source of truth — edit this!)
└── utils.ts # Utility functions
proxy.ts # Route protection (Next.js 16)
Edit lib/constants.ts — change APP_NAME and APP_DESCRIPTION at the top. Used across the header, sidebar, login page, footer, and metadata.
Edit PLAN_METADATA in lib/constants.ts to add, remove, or modify plan tiers. The plan system is data-driven — pricing page, setup wizard, config keys, env vars, and plan gating all adapt automatically. Create matching plans in Whop and connect the IDs via the setup wizard or env vars (pattern: NEXT_PUBLIC_WHOP_{PLAN_KEY}_PLAN_ID).
Protected pages go in app/dashboard/. Public pages go in app/(marketing)/. The proxy automatically protects /dashboard/* routes.
Edit app/globals.css. The starter uses Tailwind CSS v4 with CSS custom properties for theming. Modify the :root variables to change colors.
pnpm dev # Dev server with Turbopack
pnpm build # Production build
pnpm lint # ESLint
pnpm db:push # Push schema to database
pnpm db:studio # Visual database browser- Next.js 16 (App Router) + TypeScript
- Whop (OAuth 2.1 + PKCE, payments, webhooks)
- Prisma 7 + PostgreSQL
- Tailwind CSS v4
- jose (JWT sessions)
Pull requests are welcome! If you have ideas, bug fixes, or improvements, feel free to open a PR.
For feedback or questions, reach out to [email protected].
MIT