CLI
Scaffold projects and run schema generation/migrations with BTST CLIs.
BTST has two CLI packages:
@btst/codegenownsinitscaffolding (npx @btst/codegen init)@btst/cliowns low-level DB schema generation and migrations
@btst/codegen generate and @btst/codegen migrate run the aligned
@btst/cli@2.2.4 release in isolation. This avoids adding its dependency graph
or competing btst binary to the application. The delegated CLI still loads
the configuration, environment files, aliases, Better Auth adapter, and ORM
peers from the application directory.
Init (Codegen)
Use init to scaffold BTST into an existing Next.js (App Router), React Router v7, or TanStack Start project:
npx @btst/codegen initCommon flags:
| Flag | Description |
|---|---|
--framework | nextjs, react-router, or tanstack |
--adapter | memory, prisma, drizzle, kysely, or mongodb |
--plugins | Comma-separated plugin keys: blog, ai-chat, cms, form-builder, ui-builder, kanban, comments, media, route-docs, open-api, better-auth-ui (or all) |
--cwd | Target directory |
--skip-install | Skip package installation step |
--yes | Non-interactive defaults (useful in CI) |
init scaffolds and patches:
lib/stack.ts(or framework equivalent)lib/stack-client.tsxlib/query-client.ts- API and pages catch-all routes using the framework entry factories
- Global CSS imports (including plugin CSS)
- Pages layout with
QueryClientProvider, one resolved client stack, and the framework router passed toStackProvider
If root layout patching is not safe for your file shape, the command prints manual patch instructions instead of applying a destructive rewrite.
Generated plugin config entries in lib/stack.ts and lib/stack-client.tsx use camelCase config keys (for example aiChat, uiBuilder, formBuilder) even though plugin selection flags use kebab-case names.
Generated v3 layouts never repeat framework router, API, or identity wiring in plugin overrides. Replace only the plugin-specific TODO values (for example an upload function or user resolver).
better-auth-ui is an optional companion selection. It generates the auth and
account client plugins, a browser client for an existing /api/auth endpoint,
and the framework-native session refresh callback. It never generates a Better
Auth server, database schema, migrations, providers, secrets, or BTST identity
adapter. See Better Auth UI Companion.
Generate and Migrate via Codegen
If you prefer one command surface, these delegate to @btst/cli:
npx @btst/codegen generate --orm=prisma --config=lib/stack.ts --output=schema.prisma
npx @btst/codegen migrate --config=lib/stack.ts --database-url=postgres://...When a delegated command fails, fix the underlying issue and run the equivalent
npx @btst/cli@2.2.4 ... command directly.
About Better DB
BTST uses Better DB (@btst/db) as its database abstraction layer—a specialized fork of better-auth's database layer optimized for BTST's plugin architecture.
The CLI works with the dbSchema exported from your BTST configuration, which is built using Better DB's schema definition API. All plugin schemas are automatically merged into a unified schema that the CLI can process.
For v3 applications, prefer the codegen passthrough commands above. If a v2
application lists @btst/cli in its dependencies, remove it during migration;
the pinned one-off CLI keeps Better DB dependencies from polluting the consumer
graph. You can still invoke the low-level CLI directly with
npx @btst/cli@2.2.4.
Parameters
| Parameter | Command | Required | Values | Description |
|---|---|---|---|---|
--config | generate, migrate | Yes | File path (e.g., db.ts, lib/stack.ts) | Path to your BTST configuration file that exports dbSchema |
--orm | generate | Yes | prisma, drizzle, kysely | The ORM to generate schema for |
--output | generate, migrate | Yes (generate), Yes (migrate) | File path | Output file path for generated schema or migration SQL |
--database-url | generate (kysely only), migrate | Yes (kysely generate), Yes (migrate) | Database connection string | Database URL (can also use DATABASE_URL environment variable) |
Generate
Generate database schemas for your ORM from your BTST dbSchema:
npx @btst/cli@2.2.4 generate --config=lib/stack.ts --orm=prisma --output=schema.prismanpx @btst/cli@2.2.4 generate --config=lib/stack.ts --orm=drizzle --output=src/db/schema.tsKysely requires a database connection for introspection:
Using DATABASE_URL environment variable:
DATABASE_URL=sqlite:./dev.db npx @btst/cli@2.2.4 generate --config=lib/stack.ts --orm=kysely --output=migrations/schema.sqlOr using --database-url flag:
npx @btst/cli@2.2.4 generate --config=lib/stack.ts --orm=kysely --output=migrations/schema.sql --database-url=sqlite:./dev.dbnpx @btst/cli@2.2.4 generate --config=lib/stack.ts --orm=kysely --output=migrations/schema.sql --database-url=postgres://user:pass@localhost:5432/dbMigrate
Migrate your database schema directly (Kysely only). For Prisma and Drizzle, use their native migration tools.
Using DATABASE_URL environment variable:
DATABASE_URL=sqlite:./dev.db npx @btst/cli@2.2.4 migrate --config=lib/stack.tsOr using --database-url flag:
npx @btst/cli@2.2.4 migrate --config=lib/stack.ts --database-url=sqlite:./dev.dbnpx @btst/cli@2.2.4 migrate --config=lib/stack.ts --database-url=postgres://user:pass@localhost:5432/dbGenerate SQL to File
Instead of running migrations directly, generate SQL to a file:
npx @btst/cli@2.2.4 migrate --config=lib/stack.ts --output=migrations.sql --database-url=sqlite:./dev.dbProject config loading
The CLI executes your config file to extract the dbSchema, using the same
project context as the application:
- TypeScript path aliases such as
@/or~/are loaded from the project'stsconfig.jsonorjsconfig.json. - Standard Next.js environment files are loaded in precedence order. Existing process environment values continue to win.
- A bare
import "server-only"marker is ignored while evaluating the server config for schema generation; the remainder of the server import graph still executes normally. - Prisma and Drizzle adapter modules, including their ORM peers, resolve from
the application. Keep
better-authand the selected ORM installed there.
You can still override a value for one command:
SOME_VAR=value npx @btst/cli@2.2.4 generate --config=lib/stack.ts --orm=prisma --output=schema.prisma