CLI Overview
The drzl CLI analyzes Drizzle schemas and runs generators.
Quick help:
pnpm dlx @drzl/cli --helpnpx @drzl/cli --helpyarn dlx @drzl/cli --helpbunx @drzl/cli --helpEvery command shares the same output rules, the same --json contract and the same three exit codes: see Output & exit codes.
Jump to commands:
- Init: set up a starter config → /cli/init
- Analyze: inspect a schema → /cli/analyze
- Explain: what DRZL understood about one table → /cli/explain
- Doctor: what DRZL cannot type or enforce → /cli/doctor
- Generate: run configured generators, or one of them with
--only→ /cli/generate - Generate (oRPC): deprecated, see
generate --only orpc→ /cli/generate-orpc - Generate (tRPC): deprecated, see
generate --only trpc→ /cli/generate-trpc - Watch: watch schema and regenerate → /cli/watch
- Output: streams, colour,
--json, exit codes → /cli/output
Something failed? Troubleshooting is keyed by the message the CLI printed.
Every command
--json: write one JSON document to stdout and nothing else-q, --quiet: drop the progress narration on stderr; errors still print- stdout carries the answer, stderr carries the narration
- colour is off on a stream that is not a terminal, and off entirely under
NO_COLOR 0did the work,1could not do the work,2did the work and found something
All of these are documented in Output & exit codes.
Commands & Options
analyze
Analyze a Drizzle schema (TypeScript) and output a normalized Analysis.
Usage (by package manager):
pnpm dlx @drzl/cli analyze <schema> [--relations] [--validate] [--out FILE] [--json]npx @drzl/cli analyze <schema> [--relations] [--validate] [--out FILE] [--json]yarn dlx @drzl/cli analyze <schema> [--relations] [--validate] [--out FILE] [--json]bunx @drzl/cli analyze <schema> [--relations] [--validate] [--out FILE] [--json]Options:
--relations(default true): include relation inference--validate(default true): validate constraints--out <file>: write JSON to file, as a bareAnalysiswith no envelope--json(default false): print one JSON document to stdout (overrides--out)
Exits 1 when the schema could not be read at all, and 2 when it was read and issues holds an error-level entry. See Exit codes.
explain
Show what DRZL understood about one table: the type it resolved for every column, the facts the generators read off it, the constraints it will enforce, and the ones it read and could not use.
pnpm dlx @drzl/cli explain <table> [--json] [-s src/db/schema.ts] [-c drzl.config.ts]npx @drzl/cli explain <table> [--json] [-s src/db/schema.ts] [-c drzl.config.ts]yarn dlx @drzl/cli explain <table> [--json] [-s src/db/schema.ts] [-c drzl.config.ts]bunx @drzl/cli explain <table> [--json] [-s src/db/schema.ts] [-c drzl.config.ts]Options:
[table]: the table, by database name, qualified name or export name. Omit it for the index.-s, --schema <path>: the schema to read, overriding the config-c, --config <path>: which config to read the schema path from--json,-q, --quiet
Writes nothing. Exits 0 when the table was explained, 1 when the name reaches no table or more than one, or when there is no schema to read.
See Explain.
doctor
Report what DRZL cannot type or enforce in your schema, and why. Not analyze: that prints the whole Analysis and leaves you to spot the trouble in it, this prints only what will silently not work.
pnpm dlx @drzl/cli doctor [schema] [--json] [--strict] [-c drzl.config.ts]npx @drzl/cli doctor [schema] [--json] [--strict] [-c drzl.config.ts]yarn dlx @drzl/cli doctor [schema] [--json] [--strict] [-c drzl.config.ts]bunx @drzl/cli doctor [schema] [--json] [--strict] [-c drzl.config.ts]Options:
[schema]: path to the schema. Read fromdrzl.config.*when omitted.-c, --config <path>: which config to read the schema path from--json: print the report as JSON instead of prose--strict: exit2when anything is reported-q, --quiet: drop the narration on stderr; the report still prints
Exits 0 by default even with findings, because a schema carrying a customType is normal and usable. Exits 1 only when the schema could not be read at all.
See Doctor.
generate
Run configured generators from drzl.config.*.
Usage:
pnpm dlx @drzl/cli generate -c drzl.config.tsnpx @drzl/cli generate -c drzl.config.tsyarn dlx @drzl/cli generate -c drzl.config.tsbunx @drzl/cli generate -c drzl.config.tsOptions:
-c, --config <path>: path to config file-s, --schema <path>: path to the schema, overriding the config--only <kinds>: run only these generator kinds, comma separated--check: regenerate and report drift, with a diff, without writing anything--dry-run: report what would be written, and write nothing--json,-q, --quiet
Behavior:
- Analyzes your schema
- Runs each generator in
generators[], printing a file summary per kind on stdout - Says how many files it created, changed and left alone, and names the ones that are not the same as before
- Warnings, the spinner and the progress bar go to stderr, so
drzl generate > files.txtholds only the paths that were written
--only takes the kinds a config uses, read from the same list the config parser is built from, so an unknown one is refused by name rather than matching nothing. With --only and no config file present, a minimal config is built in memory, which is how one generator runs with no config at all:
npx @drzl/cli generate --schema src/db/schema.ts --only orpcSee Generate.
generate:orpc
Deprecated, and removed in 5.0. Use drzl generate --schema <schema> --only orpc, which does the same thing and can reach every config feature this command cannot.
Quickly generate oRPC routers without a config.
Usage:
pnpm dlx @drzl/cli generate:orpc <schema> -o src/api --template standard --includeRelationsnpx @drzl/cli generate:orpc <schema> -o src/api --template standard --includeRelationsyarn dlx @drzl/cli generate:orpc <schema> -o src/api --template standard --includeRelationsbunx @drzl/cli generate:orpc <schema> -o src/api --template standard --includeRelationsOptions:
-o, --outDir <dir>(defaultsrc/api)--template <name>(defaultstandard): can bestandardor a custom path--includeRelations: include relation endpoints--json,-q, --quiet
Exits 1 when the schema is missing or cannot be imported. It used to exit 0 after writing a placeholder file that read "No tables detected in analysis".
generate:trpc
Deprecated, and removed in 5.0. Use drzl generate --schema <schema> --only trpc, which does the same thing and can reach every config feature this command cannot.
Quickly generate tRPC v11 routers without a config.
pnpm dlx @drzl/cli generate:trpc <schema> -o src/api --template standard --includeRelationsnpx @drzl/cli generate:trpc <schema> -o src/api --template standard --includeRelationsyarn dlx @drzl/cli generate:trpc <schema> -o src/api --template standard --includeRelationsbunx @drzl/cli generate:trpc <schema> -o src/api --template standard --includeRelationsOptions:
-o, --outDir <dir>(defaultsrc/api)--template <name>(defaultstandard):standardorservice--includeRelations: include a lookup per single-column foreign key--servicesDir <dir>(defaultsrc/services): only consulted by--template service--json,-q, --quiet
Exits 1 when the schema is missing or cannot be imported.
See Generate (tRPC).
watch
Watch schema (and template paths) and regenerate on changes.
Usage:
pnpm dlx @drzl/cli watch -c drzl.config.ts [--only zod] --debounce 200 [--json]npx @drzl/cli watch -c drzl.config.ts [--only zod] --debounce 200 [--json]yarn dlx @drzl/cli watch -c drzl.config.ts [--only zod] --debounce 200 [--json]bunx @drzl/cli watch -c drzl.config.ts [--only zod] --debounce 200 [--json]Options:
-c, --config <path>--only <kinds>: rebuild only these generator kinds, comma separated--pipeline <name>:all | analyze | generate-<kind>(defaultall), the older spelling of--only--debounce <ms>: wait this long after the last change before rebuilding (default200)--clear: clear the terminal before each rebuild, off by default--json: emit structured JSON logs on stdout, one object per line-q, --quiet: drop the narration; errors still print--poll: force polling, which helps on WSL, Docker and network mounts
A watch has no answer to give, so everything human it prints goes to stderr. Exits 1 when there is no config, when the schema path cannot be resolved, or when --only or --pipeline names something that is not a generator kind.
--pipeline reaches every kind now. It used to carry a list of seven, and anything outside that list matched nothing at all, so drzl watch --pipeline generate-zod ran and regenerated nothing. See Watch.
init
Scaffold a minimal drzl.config.ts in the current directory.
pnpm dlx @drzl/cli initnpx @drzl/cli inityarn dlx @drzl/cli initbunx @drzl/cli initOptions:
-y, --yes: take the defaults and ask nothing--schema <path>,--generators <list>--json(implies--yes),-q, --quiet
See also:
- Output,
--jsonand exit codes: /cli/output - Config reference: /guide/configuration
- Generators:

