Skip to content
Agents tracked: 440 Downloads (7d): 202M down 19.5% GitHub stars: 10.4M Releases (7d): 607 Agent status: 1 with issuesSince last limit reset: Claude 28d · Codex 0d Updated Oct 21, 2026

Starter kit for a SaaS on Next.js

A recipe for a Next.js app with sign-up and sign-in, your own Postgres, Stripe subscriptions and transactional email, tested end to end from a clean clone. For Claude Code, Cursor, Codex or Copilot, with exact versions, licenses and the traps a test build ran into.

New to kits? Read how to use a kit.

How the kit fits together

Your agent reads the brief, builds with these parts and checks its own work before you ship. Click a part to see why it was picked.

File for your agent

AGENTS.md

The plan your agent follows, a step at a time, with a check that must pass before the next step. It also holds the stack with exact versions, the licenses and the known traps.

File for your agent

first-prompt.txt

The first message you paste into your agent. It points the agent at AGENTS.md and tells it to stop after step 1 and report.

File for your agent

.mcp.json

The MCP servers the brief lists, set up for Claude Code. The kit builder writes the same setup for Cursor, Codex or Copilot.

File for your agent

CREDITS.md

The license record of every third-party file. The brief tells the agent to add a row for every file it brings in.

You bring this

Your coding agent

The kit works with any of these. Pick yours in the kit builder and the setup files change to match.

Library knowledge

Context7

4.3.0MIT

Next.js 16, Better Auth and Stripe changed APIs within the last year; models write the old ones from memory.

By Upstash · In 1,266 of 29,413 sampled repos · v4.3.0 on npm · Agent can use it through MCP

Tool and asset data

AgentGid

If the agent needs another library or service, it asks AgentGid for one that fits your constraints.

By AgentGid · Agent can use it through MCP

Runtime

Node.js 22.12 or newer

official source

Next.js, the test runner and the Better Auth CLI each set a lowest Node version; 22.12 satisfies all of them.

Nothing to install

Framework

Next.js

16.4.0MIT

Pages, API routes and server rendering in one project; the framework most AI-built SaaS apps use.

In 1,090 of 4,663 JS/TS agent projects (23.4%) · #2 of 28 in web frameworks · v16.4.0, October 7, 2026 · MIT · Installs from a package registry

UI library

React

19.3.0MIT

Next.js renders React components.

In 1,980 of 4,663 JS/TS agent projects (42.5%) · #1 of 28 in web frameworks · v19.3.0, September 9, 2026 · MIT · Installs from a package registry

Language

TypeScript 5.9

5.9.3Apache-2.0

Types catch a webhook handler and a database schema that disagree before a customer does. TypeScript 7 is out, but create-next-app 16.4.0 still installs 5.x, and this kit was built with 5.9.

v5.9.3 · Apache-2.0 · Installs from a package registry

Styling

Tailwind CSS

4.3.3MIT

The styling that create-next-app sets up; no config file needed.

In 1,991 of 4,663 JS/TS agent projects (42.6%) · v4.3.3 · MIT · Installs from a package registry

Sign-in

Better Auth

1.7.7MIT

Sign-up, sign-in, sessions and password storage, which you should not write yourself.

In 101 of 4,663 JS/TS agent projects (2.2%) · v1.7.7 · MIT · Installs from a package registry

1 other candidate also fits.

Database access

Drizzle ORM

0.45.4Apache-2.0

Typed tables and migrations; Better Auth writes its own tables through it.

In 242 of 4,663 JS/TS agent projects (5.2%) · v0.45.4 · Apache-2.0 · Installs from a package registry

Database

PostgreSQL 16 or newer

official source

Stores users, sessions, plans and the record of processed payment events.

Nothing to install

1 other candidate also fits.

Payments

Stripe

official source

Hosted Checkout takes the card details, so they never touch your server; webhooks tell your app when a plan starts or ends.

Free tier: No monthly fee; test mode is free. Stripe takes a fee per successful payment (see stripe.com/pricing). · Agent can fetch it through an API

Email

Resend

A welcome email at sign-up, and the place to send receipts or password resets later. Without a key the app falls back to the local outbox, so nothing breaks before you create the account.

Free tier: 3,000 emails/month, 100/day, 3 domains · Paid from $20 a month · Agent can fetch it through an API

1 other candidate also fits.

Unit tests

Vitest

5.0.4MIT

Runs the webhook handler and the billing logic against a real Postgres in memory.

In 1,230 of 4,663 JS/TS agent projects (26.3%) · #1 of 42 in testing · v5.0.4 (npm registry) · MIT · Installs from a package registry

End-to-end tests

Playwright (JavaScript)

1.64.0Apache-2.0

Signs up in a real browser, upgrades, and checks that the dashboard shows the paid plan.

In 1,027 of 4,663 JS/TS agent projects (22%) · #2 of 42 in testing · v1.64.0, October 7, 2026 · Apache-2.0 · Installs from a package registry

When the agent is done

8 checks

  • npm run build, npm run lint and npm test pass, and npm run test:e2e passes against the production build.
  • The end-to-end test signs up a new user in a real browser and lands on /dashboard showing the free plan; opening /dashboard signed out redirects to /sign-in.
  • The end-to-end test clicks Upgrade, is sent to a Stripe Checkout URL (stubbed in the test), then posts a signed checkout.session.completed webhook and sees the dashboard show the paid plan after a reload.
  • The webhook route answers 400 to a wrong signature, processes the same event id only once, and a customer.subscription.deleted event moves the user back to free (unit tests).
  • No real account or key is needed for any test: Stripe keys are dummy sk_test_ and whsec_ values, and email goes to .outbox/ when RESEND_API_KEY is empty.
  • Unit tests run the billing code on PGlite with the real migrations; the end-to-end test uses a local PostgreSQL from DATABASE_URL.
  • .env.example lists every variable the app reads; secrets never use the NEXT_PUBLIC_ prefix, and .env is git-ignored.
  • The kit files are still there, and AGENTS.md still starts with this brief (the Next.js block that next dev appends at the end is fine).
After the agent

Left to you

  • Create a Stripe account, stay in test mode, and create a product with a monthly price: its id goes into STRIPE_PRICE_ID. Pay once with Stripe's test card to watch the real flow.
  • For a real webhook while developing, install the Stripe CLI and run stripe listen --forward-to localhost:3000/api/stripe/webhook; it prints the whsec_ secret for .env.
  • Create a Resend account and verify a sending domain before real users sign up; until then emails land in .outbox/.
  • Choose where the app and its database run in production; switch Stripe to live mode only after a full test-mode run there.
Files for your agentAgent tools (MCP)CodeArt, sound and contentChecksOptional, off by default

What you get

The result

A Next.js 16 app: sign-up and sign-in, a protected dashboard, a paid plan through Stripe Checkout with webhooks that switch the plan, and email for new accounts. Unit and end-to-end tests run without any real account or key.

7 files
Ready for your agent
  • AGENTS.md: the plan, with a check after every step
  • first-prompt.txt, install.txt, .mcp.json
  • CREDITS.md, CLAUDE.md, kit.json
23 parts
Every part is free or has a free tier
  • App: MIT, Apache-2.0
  • Accounts: MIT, Apache-2.0
  • Agent tools: MIT
0 of 0 asset sources allow commercial use with no credit needed.
8 / 8
Checks met in the last test build
  • Build 2, Oct 12, 2026
  • 8 things in the brief reported, 0 serious
  • Findings went back into recipe v0.3
The brief counts it as done when these 8 checks pass
  • npm run build, npm run lint and npm test pass, and npm run test:e2e passes against the production build.
  • The end-to-end test signs up a new user in a real browser and lands on /dashboard showing the free plan; opening /dashboard signed out redirects to /sign-in.
  • The end-to-end test clicks Upgrade, is sent to a Stripe Checkout URL (stubbed in the test), then posts a signed checkout.session.completed webhook and sees the dashboard show the paid plan after a reload.
  • The webhook route answers 400 to a wrong signature, processes the same event id only once, and a customer.subscription.deleted event moves the user back to free (unit tests).
  • No real account or key is needed for any test: Stripe keys are dummy sk_test_ and whsec_ values, and email goes to .outbox/ when RESEND_API_KEY is empty.
  • Unit tests run the billing code on PGlite with the real migrations; the end-to-end test uses a local PostgreSQL from DATABASE_URL.
  • .env.example lists every variable the app reads; secrets never use the NEXT_PUBLIC_ prefix, and .env is git-ignored.
  • The kit files are still there, and AGENTS.md still starts with this brief (the Next.js block that next dev appends at the end is fine).

Left to you, because no check can do it: Create a Stripe account, stay in test mode, and create a product with a monthly price: its id goes into STRIPE_PRICE_ID. Pay once with Stripe's test card to watch the real flow. For a real webhook while developing, install the Stripe CLI and run stripe listen --forward-to localhost:3000/api/stripe/webhook; it prints the whsec_ secret for .env. Create a Resend account and verify a sending domain before real users sign up; until then emails land in .outbox/. Choose where the app and its database run in production; switch Stripe to live mode only after a full test-mode run there.

The parts and why each was picked

Defaults for commercial use, free parts and Claude Code. Change them.

App

Runtime
Node.js 22.12 or newer official source

Next.js, the test runner and the Better Auth CLI each set a lowest Node version; 22.12 satisfies all of them.

Nothing to install

Framework
Next.js 16.4.0

Pages, API routes and server rendering in one project; the framework most AI-built SaaS apps use.

In 1,090 of 4,663 JS/TS agent projects (23.4%) · #2 of 28 in web frameworks · v16.4.0, October 7, 2026 · MIT · Installs from a package registry

UI library
React 19.3.0

Next.js renders React components.

In 1,980 of 4,663 JS/TS agent projects (42.5%) · #1 of 28 in web frameworks · v19.3.0, September 9, 2026 · MIT · Installs from a package registry

Language

Types catch a webhook handler and a database schema that disagree before a customer does. TypeScript 7 is out, but create-next-app 16.4.0 still installs 5.x, and this kit was built with 5.9.

v5.9.3 · Apache-2.0 · Installs from a package registry

Styling

The styling that create-next-app sets up; no config file needed.

In 1,991 of 4,663 JS/TS agent projects (42.6%) · v4.3.3 · MIT · Installs from a package registry

Installed along with them: React DOM 19.3.0, Stripe (JavaScript) 23.0.0, Tailwind CSS Turbopack loader 4.3.3, @types/node 22 22.20.5, PGlite 0.5.9, Drizzle Kit 0.31.11, node-postgres (pg) 8.23.1, @types/pg 8.23.1, Resend (Node.js) 6.32.1.

Accounts

Sign-in

Sign-up, sign-in, sessions and password storage, which you should not write yourself.

In 101 of 4,663 JS/TS agent projects (2.2%) · v1.7.7 · MIT · Installs from a package registry

Also fits: Supabase SSR.

Database access

Typed tables and migrations; Better Auth writes its own tables through it.

In 242 of 4,663 JS/TS agent projects (5.2%) · v0.45.4 · Apache-2.0 · Installs from a package registry

Database
PostgreSQL 16 or newer official source

Stores users, sessions, plans and the record of processed payment events.

Nothing to install

Also fits: Supabase.

Billing

Payments
Stripe official source

Hosted Checkout takes the card details, so they never touch your server; webhooks tell your app when a plan starts or ends.

Free tier: No monthly fee; test mode is free. Stripe takes a fee per successful payment (see stripe.com/pricing). · Agent can fetch it through an API

Email

Email

A welcome email at sign-up, and the place to send receipts or password resets later. Without a key the app falls back to the local outbox, so nothing breaks before you create the account.

Free tier: 3,000 emails/month, 100/day, 3 domains · Paid from $20 a month · Agent can fetch it through an API

Also fits: Local outbox.

Checks

Unit tests
Vitest 5.0.4

Runs the webhook handler and the billing logic against a real Postgres in memory.

In 1,230 of 4,663 JS/TS agent projects (26.3%) · #1 of 42 in testing · v5.0.4 (npm registry) · MIT · Installs from a package registry

End-to-end tests

Signs up in a real browser, upgrades, and checks that the dashboard shows the paid plan.

In 1,027 of 4,663 JS/TS agent projects (22%) · #2 of 42 in testing · v1.64.0, October 7, 2026 · Apache-2.0 · Installs from a package registry

For your agent

Library knowledge
Context7 4.3.0

Next.js 16, Better Auth and Stripe changed APIs within the last year; models write the old ones from memory.

By Upstash · In 1,266 of 29,413 sampled repos · v4.3.0 on npm · Agent can use it through MCP

Tool and asset data

If the agent needs another library or service, it asks AgentGid for one that fits your constraints.

By AgentGid · Agent can use it through MCP

The plan your agent follows

The agent works one step at a time and does not start a step until the previous one meets its "Done when" lines. The full instructions, with code, are in AGENTS.md.

  1. Scaffold · done when:
    • npm run build and npm run lint pass on the empty app.
    • The kit files are unchanged, apart from CREDITS.md rows you add and the block next dev appends to AGENTS.md.
  2. Accounts · done when:
    • A user can sign up, sign out and sign in again in the browser, and the user row has plan = 'free'.
  3. Protected dashboard · done when:
    • npm run build passes and lists /dashboard as partially prerendered.
    • Signed out, /dashboard redirects to /sign-in; signed in, it shows the plan.
  4. Billing · done when:
    • Unit tests: a signed checkout.session.completed makes the user paid; the same event twice changes nothing the second time; a bad signature gives 400; customer.subscription.deleted makes the user free again.
  5. Email · done when:
    • Signing up in the end-to-end test leaves a welcome email in .outbox/.
  6. End-to-end test · done when:
    • npm run test:e2e passes twice in a row on a fresh database.
  7. Verify · done when:
    • Every line under Definition of done is true, and anything that could not be verified is named in PROGRESS.md.

Known traps

What test builds and the official docs showed going wrong with these parts. Each one is in the brief, so the agent reads it before it gets there.

  • create-next-app 16.4.0 refuses a folder that contains AGENTS.md, CLAUDE.md, .mcp.json, kit.json or README.md ("contains files that could conflict"), and it has no flag to override that. Scaffold into a sibling folder and copy without overwriting. measured with next 16.4.0, better-auth 1.7.7, drizzle-orm 0.45.4, stripe 23.0.0 and Node 22.22, Oct 12, 2026
  • Next 16 renamed middleware.ts to proxy.ts. The old name still works with a deprecation warning; both files together fail the build; a proxy.ts that exports a function named middleware fails with "Proxy is missing expected function export name". Next.js 16 upgrade guide, and measured with next 16.4.0, better-auth 1.7.7, drizzle-orm 0.45.4, stripe 23.0.0 and Node 22.22, Oct 12, 2026
  • Synchronous cookies() and headers() are gone in Next 16: cookies().get fails type checking with "Property 'get' does not exist on type 'Promise<ReadonlyRequestCookies>'". Next.js 16 upgrade guide, and measured with next 16.4.0, better-auth 1.7.7, drizzle-orm 0.45.4, stripe 23.0.0 and Node 22.22, Oct 12, 2026
  • next lint was removed and next build no longer lints; npx next lint now reads "lint" as a project folder. Run eslint. Next.js 16 upgrade guide, and measured with next 16.4.0, better-auth 1.7.7, drizzle-orm 0.45.4, stripe 23.0.0 and Node 22.22, Oct 12, 2026
  • With cacheComponents (on in a fresh create-next-app 16.4.0 project), a page that reads the session outside <Suspense> fails next build with "encountered uncached or runtime data during prerendering". measured with next 16.4.0, better-auth 1.7.7, drizzle-orm 0.45.4, stripe 23.0.0 and Node 22.22, Oct 12, 2026
  • @better-auth/cli is stuck at 1.4.21 and deprecated; the CLI is now the auth package (npx auth@1.7.7 generate). auth migrate refuses the Drizzle adapter: generate the schema, then migrate with Drizzle Kit. Better Auth docs, and measured with next 16.4.0, better-auth 1.7.7, drizzle-orm 0.45.4, stripe 23.0.0 and Node 22.22, Oct 12, 2026
  • getSessionCookie() only checks that a session cookie exists; it does not validate it. Check the session again in the page or route with auth.api.getSession(). Better Auth docs
  • Stripe's constructEvent needs the raw body: a parsed object fails with "Webhook payload must be provided as a string or a Buffer", and a re-serialized body with "No signatures found matching the expected signature". In a route handler, read it with await req.text(). Stripe docs, and measured with next 16.4.0, better-auth 1.7.7, drizzle-orm 0.45.4, stripe 23.0.0 and Node 22.22, Oct 12, 2026
  • Stripe may deliver the same event more than once and does not guarantee order: record processed event ids, and never let the handler depend on which event came first. Stripe docs
  • new Resend() with an empty or missing key throws "Missing API key" at once, so a client created at import time breaks the build and every test; emails.send() reports failures in its result instead of throwing. measured with resend 6.32.1, Oct 12, 2026
  • Drizzle's PostgreSQL getting-started page installs the @rc (1.0 release candidate) versions of drizzle-orm and drizzle-kit. Keep the pinned 0.45.4 and 0.31.11 from the Stack; Better Auth 1.7.7 supports both lines. Drizzle docs and Better Auth's peer dependencies, Oct 12, 2026
  • With cacheComponents, up to three visited routes stay in the page, hidden inside React's <Activity>: a Playwright locator such as getByLabel('Email') can match a hidden copy and fail strict mode. getByRole skips hidden elements. measured with next 16.4.0, better-auth 1.7.7, drizzle-orm 0.45.4, stripe 23.0.0 and Node 22.22, Oct 12, 2026
  • create-next-app's .gitignore ignores .env*, which includes .env.example; a clean clone then has no example file. measured with next 16.4.0, better-auth 1.7.7, drizzle-orm 0.45.4, stripe 23.0.0 and Node 22.22, Oct 12, 2026
  • Vitest 5 wants @types/node 22 or newer as a peer; create-next-app installs ^20, and npm install vitest on its own then fails with ERESOLVE until @types/node is upgraded. The dev install line in install.txt upgrades both together, so it does not hit this. measured with next 16.4.0, better-auth 1.7.7, drizzle-orm 0.45.4, stripe 23.0.0 and Node 22.22, Oct 12, 2026

Checks on this kit

  • Note Next.js 16 changed several APIs that most examples online still use (middleware.ts, synchronous cookies(), next lint). Follow this brief and the docs bundled with the installed version. Source

What happened when an agent built from it

The recipe was given to a fresh coding agent in a clean sandbox, twice. The agent got only the kit files. It had to build the project and write down everything in the brief that was wrong, missing or unclear.

Build 1 · brief v0.1 · Oct 12, 2026

8 of 8
lines of the definition of done met
10
things in the brief reported as wrong, missing or unclear
2
serious: would have lost a file or wiped data

The scaffold's .gitignore hid .env.example from git, and the brief did not say which database the end-to-end setup may reset. The scaffold command also lacked --src-dir, so the first scaffold had to be redone.

Build 2 · brief v0.2 · Oct 12, 2026

8 of 8
lines of the definition of done met
8
things in the brief reported as wrong, missing or unclear
0
serious: stopped the build or shipped a flaw

One retry: Better Auth refused sign-up because BETTER_AUTH_URL said localhost while the browser used 127.0.0.1. Also fixed: lint ignoring the clean copy, CREDITS leaving out devOptional test tools, where stripe-mock is installed, and password fields in Playwright.

Result of the last build. A Next.js 16 SaaS starter with sign-up, a protected dashboard, Stripe Checkout and webhooks (stripe-mock, signed test events) and a welcome email; 17 unit and 2 browser tests pass against a production build, also in a fresh clone set up from the README alone, with no real account or key. Its findings went back into the recipe, which is now at v0.3. That version has not been built again as a whole.

Checked again on Oct 19, 2026. AgentGid checks every recipe each week, without a model: 17 pinned packages all still exist on their registries, 10 of them have a newer release than the tested pin; 24 links in the brief: all open (1 refused automated requests, which some sites do). npm lines are checked pin by pin, not installed.

Not checked by anyone yet

  • A real Stripe account: real Checkout, the customer portal and webhooks through the Stripe CLI
  • Real email delivery through Resend
  • The Supabase variant (its local stack needs Docker images that could not be downloaded)
  • A production host, macOS and Windows

The kit files

Put them in an empty project folder, open your coding agent there and paste the first prompt (Claude Code first asks you to approve the MCP servers in .mcp.json). These are the files for Claude Code with the default answers; the kit builder writes them for Cursor, Codex, Copilot or another agent, and for other choices. Full guide: how to use a kit.

FileWhat it isSize
AGENTS.mdThe brief: what to build, stack and versions, licenses, plan with checks, known traps361 lines
CREDITS.mdThe license record of every third-party file39 lines
first-prompt.txtYour first message to the agent8 lines
install.txtInstall commands with exact versions7 lines
CLAUDE.mdOne line that imports AGENTS.md for Claude Code1 lines
.mcp.jsonThe MCP servers the brief lists, for Claude Code15 lines
kit.jsonThe kit as data: parts, versions, checks379 lines

Download all (.zip)

first-prompt.txt the agent stops after each step and reports
Read AGENTS.md from top to bottom before you do anything else. The kit files it lists are already in this folder.

Then do step 1 of the plan and stop. Report back with:
1. the commands you ran,
2. what each "Done when" check showed (a screenshot or the output),
3. anything in AGENTS.md that turned out to be wrong, missing or out of date.

Do not start step 2 until I reply.
Or let it run the whole plan
Read AGENTS.md from top to bottom before you do anything else. The kit files it lists are already in this folder.

Then work through the plan in order. After each step, run its "Done when" checks yourself and write one line in PROGRESS.md: the step, what you checked, and the result.
You may install the packages and download the files that AGENTS.md lists without asking. Stop and ask me only for what its "Before you start" section says needs a person.
When a check fails, fix the cause and run it again. If it still fails after two real fixes, stop and tell me what you tried.
Keep a list in PROGRESS.md of anything in AGENTS.md that turned out to be wrong, missing or out of date.
When every line of the Definition of done is true, stop and show me how to run it.
install.txt
# system packages (use your OS package manager)
postgresql

node --version   # must print v22.12 or newer
# scaffold first (Plan, step 1), then:
npm install --save-exact next@16.4.0 react@19.3.0 better-auth@1.7.7 drizzle-orm@0.45.4 react-dom@19.3.0 stripe@23.0.0 pg@8.23.1 resend@6.32.1
npm install -D --save-exact typescript@5.9.3 tailwindcss@4.3.3 vitest@5.0.4 @playwright/test@1.64.0 @tailwindcss/turbopack@4.3.3 @types/node@22.20.5 @electric-sql/pglite@0.5.9 drizzle-kit@0.31.11 @types/pg@8.23.1

Other versions of this kit

Accounts and database

Your own PostgreSQL with Better Auth keeps every user record in a database you control and needs no vendor account. Supabase hosts the database and the sign-in for you, with a free plan; running it locally needs Docker.

Own PostgreSQL (this page) Supabase

Other versions were not test-built as a whole: the kit says which parts differ from the tested one.

Ask for this kit from your agent

Agents connected to the AgentGid MCP server get the same kit without this page: list_recipes(), then plan_project({"recipe": "saas-starter", "answers": {"agent": "cursor"}, "files": true}). Every brief also tells the agent to ask AgentGid before it adds a part that is not listed.

Recipe saas-starter v0.3. Data snapshot Oct 12, 2026: versions, licenses and prices change, so check the linked pages before you ship.

Comments

  • Built something with this kit? Share what worked, what broke and what you changed.

Other kits