Create Warlock
create-warlock is the official project scaffolder. One command and a short setup flow later you have a complete, configured Warlock project that boots: choose API-only or full-stack web, then a database unless a database flag already supplied it. Prefer the old style? --interactive restores the full long-form wizard.
Migrating an existing app? Start with the v5 migration guide.
pnpm create warlock my-appcd my-appWith a terminal, that command asks for the project name (if you did not pass one), API-only or full-stack web, and a database unless --db or --no-db already supplied it. The database selector offers MongoDB and PostgreSQL, shows MySQL as disabled, and includes None for a database-free app. Everything else — package manager, optional features, git, JWT secrets — takes a sensible default, printed as a summary after scaffolding, with the flag to change each one. See Headless / non-interactive mode below for scripting it fully, or --interactive for the question-by-question flow.
What lands is a ready-to-run app: the src/app (one folder per feature) + src/config (one file per subsystem) layout, a warlock.config.ts, decorators already enabled in tsconfig.json, and a dev server you start with pnpm dev.
Headless / non-interactive mode
Section titled “Headless / non-interactive mode”create-warlock is fully headless: every prompt has a flag that answers it, --yes takes the default for anything you leave unset, and it works with no terminal at all — CI, a script, an agent. There are three modes:
- Default (a TTY, no
--yes, no--interactive) — asks the project name (if not already given), API-only or full-stack web (--stack), then a database unless--dbor--no-dbalready supplied it. The stack is the only choice that changes the generated app’s shape. --yes(or no TTY at all) — fully headless. Every answer comes from a flag or its default; nothing is ever prompted, and stdin is never read.--interactive(alias--customize) — the full long-form wizard, one prompt at a time: project name, package manager, database driver, features, AI providers, git, JWT.
# Scripting it in CI, or driving it from an agent: one command, zero promptspnpm create warlock my-app --yes \ --db=postgres --pm=pnpm --stack=web \ --features=test,redis --ai=ai-openai \ --git --jwt --agents=claude,cursor
# The one structural fork, still headlesspnpm create warlock my-web-app --yes --stack=web
# The full long-form wizard, one prompt at a timepnpm create warlock --interactiveThe first positional argument (or --name) is the project name. Value flags accept either --db=postgres or --db postgres. Unknown --db, --features, --ai, --pm, or --agents keys fail fast — before anything is written to disk — so a typo (or a hostile value) never leaves you with a half-scaffolded project.
| Flag | Takes value | Default | Purpose |
| --- | --- | --- | --- |
| <positional> / --name | yes | — (required) | Project name + target directory |
| --stack | yes | api | api or web — the structural choice; web seeds the web feature by default |
| --db / --no-db | yes / no | mongodb | Database driver — mongodb, postgres, or none (--no-db is shorthand for --db=none) |
| --pm | yes | inferred (npm_config_user_agent or the system) | Package manager — must be npm / yarn / pnpm / bun; any other value is rejected before scaffolding starts |
| --features | yes (CSV) | none, or ["web"] when --stack=web and --features is not given | Comma-separated optional feature keys |
| --ai | yes (CSV) | none | Comma-separated AI provider keys (auto-pulls @warlock.js/ai) |
| --agents | yes (CSV) | claude | Comma-separated agent-kit targets to derive docs/skills for — validated against the published target list, cached after the first lookup |
| --git / --no-git | no | off | Force-enable or force-disable git initialization |
| --jwt / --no-jwt | no | off | Force-enable or force-disable JWT secret generation |
| -y, --yes | no | off | Skip every prompt and accept defaults for anything unset |
| --interactive, --customize | no | off | Restore the full long-form interactive wizard |
| -h, --help | no | — | Print usage (every flag + its default) and exit |
| -v, --version | no | — | Print the installed create-warlock version and exit |
-h/--help and -v/--version short-circuit before anything else runs — no prompt, filesystem write, or network call, and --help wins even over a positional project name.
It fails loudly without a TTY
Section titled “It fails loudly without a TTY”Without a terminal, --yes is not even required — when stdin isn’t a TTY (CI, a script, a container, an agent harness), the scaffolder never tries to prompt, regardless of which mode was requested. If the flags already answer everything it needs, it just scaffolds. Prompting is the fallback, not the precondition.
The one thing that can’t fall back to a default is the project name. With no TTY and no name given (neither positional nor --name), the run fails immediately and names exactly what to pass instead of hanging on a prompt nobody can answer:
A project name is required and no terminal is available to ask for one. Pass it asthe first argument or --name=<name>. Non-interactive flags: --yes, --pm=<npm|yarn|pnpm>,--db=<driver>|--no-db, --features=<list>, --ai=<list>, --git|--no-git, --jwt|--no-jwt.AI choice in Customize
Section titled “AI choice in Customize”AI remains optional in the long-form wizard. Press Enter with no AI selections
to skip it. The AI multiselect also places None last; choosing it alone has
the same result. None cannot be combined with an AI provider or capability
package, so the wizard shows a warning and returns to the AI selector with
the non-None selections retained for correction. Headless --ai flags are
unchanged.
Exit codes
Section titled “Exit codes”| Exit code | When |
| --- | --- |
| 0 | Success — including --help, --version, and a user cancelling an interactive prompt (Ctrl+C / Esc). |
| 1 | A validation failure (unknown --pm/--db/--features/--ai/--agents value, missing project name with no TTY to ask), the target directory already exists, or the scaffold itself failed partway through (dependency install, git init, feature addition, or cache warm-up). |
A scaffold failure surfaces the error and halts — there is no automatic rollback of partially-written files.
Scaffolding without a database
Section titled “Scaffolding without a database”Not every app needs a database. Pick None in the wizard’s database step — or pass --db=none (--no-db is a shorthand) — and the scaffold leaves the database out entirely: no driver is selected, no driver package is installed, and the template’s src/config/database.ts is removed. Warlock’s database connector is gated on that config file, so the app boots cleanly with no database wired.
# A database-free API in one commandpnpm create warlock my-api --yes --no-db --features=testWhere to go next
Section titled “Where to go next”- Full walkthrough → Core · Installation — every question, the scaffolded file tree, and booting the dev server, step by step.
- Your first endpoint → Core · Getting Started — from a fresh project to a working route.
- Scaffold as you build → Core · Generators —
warlock generate.module,generate.controller, and the rest of the family.