← saas-init.dev

Documentation

Get started in 5 minutes.

Everything you need to scaffold, extend, and ship.

Quick start

No install needed. Run directly with npx:

npx saas-init@latest init

Or install globally:

npm install -g saas-init

Requirements

  • Node.js ≥ 18
  • pnpm — used to install dependencies in generated projects (npm i -g pnpm)

Prompt sequence

The CLI walks you through six questions. Every question has a sensible default — just press Enter to accept it.

  1. Project name — lowercase, npm-valid (e.g. my-saas)
  2. Output directory — defaults to ./{name}
  3. Next.js version — 15 or 16 (default: 16)
  4. Auth provider — Clerk, NextAuth, or Supabase Auth
  5. Database — Postgres, SQLite, or Supabase
  6. Payments — Stripe, Lemon Squeezy, or none
  7. Email — Resend, Postmark, or none

After confirming the summary, saas-init writes all files and optionally runs pnpm install in the output directory.

Stack options

CategoryOptions
AuthClerk, NextAuth, Supabase Auth
DatabasePostgres + Drizzle, SQLite + Drizzle, Supabase
PaymentsStripe, Lemon Squeezy, None
EmailResend, Postmark, None

What gets generated

Every project includes:

  • Next.js App Router scaffold — layout, globals, tsconfig, postcss, components.json
  • Tailwind v4 + shadcn/ui — pre-installed and configured
  • Landing page — hero, problem, value, CTA sections ready to customise
  • Auth — provider files, middleware, sign-in/sign-up routes
  • Database — Drizzle config, schema, migrations
  • Payments — full webhook handler, subscription lifecycle (when chosen)
  • Email — transactional email client wired to real events (when chosen)
  • Docker — Dockerfile + docker-compose.yml
  • GitHub Actions — CI pipeline for test + lint on every push
  • .env.local — pre-filled with the values you entered during init

Adding a new provider

saas-init is built to be extended. Adding a new auth, database, payment, or email provider takes six steps.

1. Add templates

Create files under templates/<category>/<provider>. Use {{key}} placeholders for values that come from ProjectConfig.

2. Create a generator

// src/generators/<category>/<provider>.ts
import { writeTemplate, appendEnv } from '../../utils/files.js'
import { mergeDeps } from '../../utils/deps.js'

export async function generate(config: ProjectConfig, outDir: string): Promise<void> {
  await writeTemplate(
    path.join(TEMPLATES_DIR, 'lib/client.ts'),
    path.join(outDir, 'lib/client.ts'),
    {}
  )
  const pkg = await fs.readJson(path.join(outDir, 'package.json'))
  pkg.dependencies = mergeDeps(pkg.dependencies, { '<package>': '^1.0.0' })
  await fs.writeJson(path.join(outDir, 'package.json'), pkg, { spaces: 2 })
  await appendEnv(outDir, { MY_API_KEY: '' })
}

3. Register the generator

Add it to the relevant map in src/generators/index.ts.

4. Update types

Add the new value to the union type and Zod enum in src/types.ts.

5. Add a prompt option

Add an entry to the relevant prompt in src/prompts/<category>.ts.

6. Write tests

Add a test file at tests/generators/<category>/<provider>.test.ts following the patterns of existing generator tests.

Contributing

PRs are welcome. Open an issue first for anything substantial.

git clone https://github.com/oleg-koval/saas-init
cd saas-init
pnpm install
pnpm test

Support

Found a bug or have a question? Open an issue on GitHub or email [email protected].