StartupKitstartupkit
Getting Started

Scaffold a SaaS App

Create a production-ready SaaS project from the StartupKit template

Scaffold a blank SaaS application — Next.js 16 on Cloudflare Workers, auth on D1, Stripe billing, transactional email — with one command. This is the same flow the CLI's init command performs on your machine.

1. Scaffold the project

npx startupkit init "My SaaS"
cd my-saas

This creates the project folder from 01-studio/startupkit/templates/repo, initializes a fresh git history, runs bun install, and installs the startupkit agent skill so your AI agents know how to operate the stack.

What's inside:

  • Next.js 16 App Router served by a single Cloudflare Worker (OpenNext)
  • better-auth — email OTP sign-in + optional Google OAuth, sessions on Cloudflare D1
  • Stripe billing — checkout, customer portal, webhook subscription sync
  • Transactional email — Cloudflare Email binding + React Email templates
  • shadcn-style UI, Tailwind 4, next-intl, vitest, CI workflow

Options: --dir <path> (destination), --repo <user/repo[#branch]> (template source), --no-install (skip bun install).

Prefer plain degit?

npx degit 01-studio/startupkit/templates/repo my-saas

2. Local environment

cd apps/web
cp .env.example .env.local
cp .dev.vars.example .dev.vars
openssl rand -base64 32

Put the generated value as BETTER_AUTH_SECRET in both files — they must match or sessions will randomly fail.

3. Create the database

The template uses Cloudflare D1 (serverless SQLite):

bunx wrangler d1 create startupkit-db

Copy the returned database_id into wrangler.jsonc and wrangler.next-dev.jsonc, then apply the migrations locally:

bun run migrate

4. Run it

bun run dev
  • App → http://localhost:3000
  • Email preview → http://localhost:3001 (React Email dev server)

Sign up with any email — locally the OTP prints to the dev server log instead of being emailed.

5. Wire up billing (optional)

  1. Create a recurring "Pro" product in Stripe (monthly + yearly prices)
  2. Set STRIPE_SECRET_KEY, STRIPE_PRICE_PRO_MONTHLY, STRIPE_PRICE_PRO_YEARLY, and STRIPE_WEBHOOK_SECRET in .env.local
  3. Point a Stripe webhook at https://<your-domain>/api/stripe/webhook for checkout.session.completed and customer.subscription.*

Upgrade buttons appear on /settings once STRIPE_SECRET_KEY is set.

6. Deploy

cd apps/web
bunx wrangler secret put BETTER_AUTH_SECRET
bunx wrangler secret put BETTER_AUTH_URL     # https://yourdomain.com
bun run migrate:remote                       # prod D1 migrations
bun run deploy                               # build + upload + shift traffic

Add your domain to the routes block in wrangler.jsonc for a custom domain. Verify a sending domain in Cloudflare Email Service so transactional email delivers (the EMAIL binding is pre-declared).

7. Push to GitHub

gh repo create <org>/<name> --private --source . --push

CI (lint, typecheck, test) runs automatically on every push.

What's next

  • Read the scaffold's own README.md — full setup reference
  • CLI Reference — research commands + auth
  • MCP Setup — give your agents research tools

On this page