Build stage — for AI agents and the people who run them
Hand your agent a SaaS to ship.
Free, and done in one paste.
This page is built to be pasted. Copy the handoff prompt below into Claude Code, Cursor, OpenCode, or any coding agent. It scaffolds a production-ready SaaS (Next.js on Cloudflare, auth on D1, Stripe billing, transactional email, a /kit listing page), wires up GitHub, and deploys. Every step has a verification; the agent stops and reports if one fails.
1 · Scaffold the app (or let the agent run it)
2 · Give the agent the startupkit skill (optional)
3 · Add the research + launch tools via MCP (optional, free key at /pro)
The agent handoff prompt
Replace <Product Name>, <org>, and <yourdomain.com> before pasting.
You are scaffolding a new SaaS app from the StartupKit template and taking it
through local setup, GitHub repo creation, and Cloudflare deployment. Follow
the steps in order and verify each before continuing.
PREREQUISITES — verify these first and stop if any fail:
- bun --version
- gh auth status (GitHub CLI, authenticated)
- bunx wrangler whoami (Cloudflare access, or ask me for CLOUDFLARE_API_TOKEN)
STEP 1 — SCAFFOLD
- Run: npx startupkit init "<Product Name>" && cd <slugified-name>
- This clones 01-studio/startupkit/templates/repo (private — needs my git
credentials), inits a fresh git history, runs bun install, and installs the
startupkit agent skill to .agents/skills/startupkit/.
STEP 2 — LOCAL ENV (apps/web/)
- cp .env.example .env.local && cp .dev.vars.example .dev.vars
- Generate once: openssl rand -base64 32
- Put the SAME value as BETTER_AUTH_SECRET in both files.
- Verify: bun run typecheck passes; bun run migrate applies 2 migrations;
bun run test passes.
STEP 3 — CLOUDFLARE D1
- cd apps/web && bunx wrangler d1 create startupkit-db
- Put the returned database_id into BOTH wrangler.jsonc and
wrangler.next-dev.jsonc (replace REPLACE_WITH_YOUR_D1_DATABASE_ID).
- Verify: bunx wrangler d1 list shows startupkit-db.
STEP 4 — RUN LOCALLY
- From repo root: bun run dev (app :3000, email preview :3001)
- Verify: GET / returns 200; GET /dashboard returns 307 (auth gate);
GET /kit returns 200 with an X-Robots-Tag: noindex, nofollow header;
GET /robots.txt disallows /kit;
POST /api/auth/email-otp/send-verification-otp with
{"email":"[email protected]","type":"sign-in"} returns 200 — in dev the OTP
prints to the server log instead of being emailed.
STEP 5 — OPTIONAL INTEGRATIONS
- Stripe: create a recurring "Pro" product (monthly + yearly prices); set
STRIPE_SECRET_KEY, STRIPE_PRICE_PRO_MONTHLY, STRIPE_PRICE_PRO_YEARLY,
STRIPE_WEBHOOK_SECRET in apps/web/.env.local; webhook endpoint
https://<yourdomain.com>/api/stripe/webhook for checkout.session.completed
and customer.subscription.*.
- Google OAuth (optional): GOOGLE_CLIENT_ID / GOOGLE_CLIENT_SECRET in
apps/web/.env.local.
- Email: verify a sending domain in Cloudflare Email Service; set EMAIL_FROM
in apps/web/lib/email.ts.
STEP 6 — RENAME THE PRODUCT
- Replace startupkit with the product name: package names in apps/web/package.json,
root package.json script filters, worker name startupkit-web, db name startupkit-db.
- Replace yourdomain.com in apps/web/lib/urls.ts, apps/web/lib/email.ts,
apps/web/wrangler.jsonc routes.
- Update apps/web/public/favicon.svg, apps/web/i18n/messages/en.json,
apps/web/app/page.tsx, and the root README.md.
- Rebrand the listing kit (it ships describing StartupKit itself):
1. apps/web/lib/site.ts — name, url, oneLiner, tagline (≤10 words),
short (≤60 chars), category, model, platform, brandColor (from the new
favicon), socials (only accounts that exist), surfaces to screenshot.
This file also drives the site's <meta description> and OG tags.
2. apps/web/app/kit/page.tsx — rewrite the five long-description tiers
from the product's marketing copy (2–4 short paragraphs each, different
opening sentence per tier, ending with the URL), the Tags: line, the
Submit-next rows, and Still-needed list. Leave Confirmed live listings empty.
3. bun run kit:assets --skip-screenshots (logos + OG + X/LinkedIn/Facebook/
YouTube banners from the new favicon), then with the app running: KIT_BASE_URL=http://localhost:3000
bun run kit:assets --only=screenshots. Commit apps/web/public/kit/.
- Verify: bun run test passes (site.ts constraints are tested); GET /kit
shows no "StartupKit", "startupkit.com", or placeholder text; pasting the
site URL into a link-preview tool shows the new OG image + description.
STEP 7 — GITHUB
- gh repo create <org>/<repo-name> --private --source . --push
- Enable dependabot security updates. Version updates already come from
.github/dependabot.yml in the template, but security updates are per-repo
settings and off by default for private repos:
gh api -X PATCH repos/<org>/<repo-name> -f security_and_analysis[dependabot_alerts]=enabled -f security_and_analysis[dependabot_security_updates]=enabled
- Verify: gh api repos/<org>/<repo-name> --jq '.security_and_analysis'
reports dependabot_alerts and dependabot_security_updates both "enabled".
- Verify: CI (lint + typecheck + test) is green on the first push.
- gh secret set CLOUDFLARE_API_TOKEN --repo <org>/<repo-name> --body "<API
token with Workers + D1 edit permissions>"
- gh secret set CLOUDFLARE_ACCOUNT_ID --repo <org>/<repo-name> --body "<account
id from bunx wrangler whoami>" (these power .github/workflows/deploy.yml,
which auto-deploys main: D1 migrations first, then the worker version)
STEP 8 — DEPLOY
- cd apps/web
- bunx wrangler secret put BETTER_AUTH_SECRET (same value as Step 2)
- bunx wrangler secret put BETTER_AUTH_URL (https://<yourdomain.com>)
- bun run migrate:remote
- bun run deploy
- Verify: https://<yourdomain.com> returns 200; sign-up works; Stripe webhook
shows 200 deliveries.
- From now on, pushes to main deploy automatically (migrations apply before
the new code ships); the deploy/migrate:remote scripts stay for manual runs.
RULES
- Never commit .env.local or .dev.vars (gitignored).
- Do not push or deploy without showing me the plan first.
- If a verification fails, stop and report — do not improvise fixes.What the agent ships
Next.js 16 on Cloudflare Workers
App Router + OpenNext, one Worker serves everything. Versioned deploys with bun run deploy.
Auth on D1
better-auth with email OTP sign-in and optional Google OAuth. Sessions in Cloudflare D1, versioned migrations.
Stripe billing
Checkout, customer portal, webhook subscription sync. One 'pro' plan, monthly + yearly prices.
Transactional email
React Email templates with a preview server, delivered via Cloudflare Email Service.
Listing kit at /kit
Logos, OG image, social banners for every platform, screenshots, paste-ready descriptions, and a 15-directory submission tracker. Regenerate with bun run kit:assets.
Agent-ready repo
CI (lint, typecheck, test), the startupkit skill pre-installed, and a README the agent can follow.
Verified at every step
The handoff prompt requires typecheck, tests, migrations, and HTTP checks to pass before it moves on.
Full walkthrough in the docs. Then let the agent research the market and launch it. Reading this page with an agent? Point it at /llms.txt. Agent-specific guides: /claude-code · /cursor · /opencode · /hermes · /codex.