Create an app
The interactive and non-interactive create-saas-starter generate flows.
create-saas-starter generate is the command that produces an app. It runs in
two modes: an interactive prompt flow, or a fully non-interactive flow driven by
flags.
Interactive
Run generate with no flags:
npx create-saas-starter generateIt asks four things, in order:
- Project name — becomes both the output directory and the generated
package.jsonname. Required; the default placeholder ismy-app. - Package manager —
pnpm,npm,bun, oryarn. Pre-selected to the manager that invoked the CLI (detected viapackage-manager-detector), falling back topnpm. - Features — a multi-select of every prunable feature, all pre-checked. The
core features (
auth,orgs) are always on and aren't shown as toggles. See the feature picker for how selections resolve. - Dashboard shell — a single-select for the dashboard chrome layout:
topnav(the classic top nav, the default),sidebar,vercel(header + tabs), orstripe(sidebar + top bar). All four render the same navigation; the choice deletes the other three shells and points the app at the one you picked.
The app is written to a new directory named after the project, relative to your current working directory. If that directory already exists and is non-empty, generation refuses to overwrite it and aborts.
Non-interactive
Pass --yes to skip every prompt and generate from flags and defaults. --name
is required in this mode:
# The full reference app (all prunable features on)
npx create-saas-starter generate --name my-app --yes
# Only the features you name (plus their dependencies and core)
npx create-saas-starter generate --name my-app --features billing,usage --yes
# The core-only app (auth + orgs, everything prunable removed)
npx create-saas-starter generate --name my-app --features core --yes
# Pick a dashboard shell other than the default topnav
npx create-saas-starter generate --name my-app --shell sidebar --yesWith --yes and no --features, you get the full reference app — every
prunable feature on. The package manager defaults to the detected one.
Flags
| Flag | Purpose |
|---|---|
--name <name> | Project name and output directory. Required with --yes. |
--features <list> | Comma-separated feature list, or core for the core-only app. Absent ⇒ ask interactively (or, with --yes, all prunable on). |
--shell <name> | Dashboard shell: topnav | sidebar | vercel | stripe. Absent ⇒ ask interactively (or, with --yes, defaults to topnav). |
--package-manager <pm> | pnpm | npm | bun | yarn. Default: detected. |
--database-url <url> | Prefills the generated .env's DATABASE_URL (never .env.example). |
--yes | Non-interactive: use flags and defaults, skip all prompts. |
--git / --no-git | Initialize a git repository. Default: on; --no-git skips it. |
The --features value is trimmed, split on commas, de-duplicated, and empties
are dropped. The sentinel core (case-insensitive) means "core only". Passing an
unknown feature name is a loud error naming the offenders.
Dependencies are resolved for you
You only name the features you care about. The generator pulls in each one's
required dependencies automatically — --features usage also gives you
billing, flags, jobs, and email. See
the feature picker.
What generate does
Once it has a name, package manager, and feature selection, generate runs the
end-to-end pipeline:
- Copy the reference app into the target directory (build artifacts, local env files, and the block registry are excluded).
- Prune — delete deselected features' files and strip their
@featuremarker regions from every remaining file. - Rewrite — collapse the monorepo into a single standalone
package.json, drop pruned features' dependencies/scripts/env/compose services, and deletefeatures.json. - Stamp and document — write the generated README, the
.saas-starter.jsonstamp, and the.env(with your--database-urlif given). - Verify in place — install dependencies, generate the Prisma client and Next types, and typecheck. Any failure is a loud abort; the app is left on disk for inspection, never handed over as if it worked.
- Format and commit — a Prettier pass, then
git initand an initial commit (unless--no-git).
For the full mechanics of each step, see the generate flow.
When it finishes, it prints the next steps — covered in First run.