Skip to content

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.

Terminal window
pnpm create warlock my-app
cd my-app

With 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.

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:

  1. 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 --db or --no-db already supplied it. The stack is the only choice that changes the generated app’s shape.
  2. --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.
  3. --interactive (alias --customize) — the full long-form wizard, one prompt at a time: project name, package manager, database driver, features, AI providers, git, JWT.
Terminal window
# Scripting it in CI, or driving it from an agent: one command, zero prompts
pnpm 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 headless
pnpm create warlock my-web-app --yes --stack=web
# The full long-form wizard, one prompt at a time
pnpm create warlock --interactive

The 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.

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 as
the 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 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 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.

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.

Terminal window
# A database-free API in one command
pnpm create warlock my-api --yes --no-db --features=test
  • 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.