CLI
The Strav CLI (strav) provides commands for migrations, code generation, package management, and database management.
Running commands
bun strav <command> [options]
The CLI entry point is strav.ts at the project root.
Available commands
generate:migration
Generates migration files by diffing your schemas against the live database.
bun strav generate:migration
bun strav generate:migration -m "add user roles"
bun strav generate:migration --scope public -m "add public schema tables"
Options:
-m, --message <message>— Migration description (default:'migration').-s, --scope <scope>— Domain to target (default:'public'). Supports multi-domain database architectures.
- Loads all schemas from
database/schemas/. - Introspects the live database.
- Computes the diff (new tables, altered columns, new indexes, etc.).
- Writes migration files to
database/migrations/<timestamp>_<message>/.
migrate
Applies all pending (unapplied) migrations.
bun strav migrate
bun strav migrate --scope public
Migrations are applied in order and grouped into a batch. Each run creates a new batch number.
Options:
-s, --scope <scope>— Domain to migrate (default:'public').
rollback
Reverts migrations by batch.
bun strav rollback # roll back the last batch
bun strav rollback --batch 3 # roll back batch 3 specifically
bun strav rollback --scope public
Options:
--batch <number>— Target a specific batch.-s, --scope <scope>— Domain to rollback (default:'public').
compare
Prints a read-only diff between your schemas and the live database. Does not modify anything.
bun strav compare
Output is color-coded:
- Green — new items to create.
- Red — items to drop.
- Yellow — items to modify.
fresh
Destructive reset — drops everything and rebuilds from scratch.
bun strav fresh
Safety checks:
- Requires
APP_ENV=local. - Prompts for a random 6-digit confirmation code.
- Drops all tables (
DROP TABLE ... CASCADE). - Drops all enum types.
- Deletes all migration files.
- Generates a fresh migration from current schemas.
- Runs the new migration.
generate:models
Generates TypeScript model classes and enum files from your schema definitions. Does not require a database connection.
bun strav generate:models
Output directories are configured via config/generators.ts (see the Generators guide).
What it produces:
app/models/<entity>.ts— Model class extendingBaseModelwith decorators, typed properties, and relationships.app/enums/<entity>.ts— TypeScript enum definitions extracted from schema enum fields.app/models/index.ts— Barrel export for all model classes.app/enums/index.ts— Barrel export for all enum types.
// Generated by Strav -- DO NOT EDIT.
generate:api
Generates the full application layer from your schema definitions: event constants, validators, policies, services, and controllers. Does not require a database connection.
bun strav generate:api
Output directories are configured via config/generators.ts (see the Generators guide).
What it produces (per non-association schema):
app/events/<entity>.ts— Event constant object (e.g.,UserEvents.CREATED).app/validators/<entity>_validator.ts— Validation rule sets forstoreandupdate.app/policies/<entity>_policy.ts— Policy class skeleton with archetype-specific methods.app/services/<entity>_service.ts— Service class wrapping model CRUD + event dispatch.app/http/controllers/<entity>_controller.ts— Controller with route handlers (validate → service → response).start/api_routes.ts— Route file wiring all controllers to the router.- Barrel
index.tsfiles for each output directory.
append instead of create, component schemas omit store/destroy, etc.
generate:key
Generates a cryptographic application key and writes it to your.env file.
bun strav generate:key
bun strav generate:key --force
Options:
-f, --force— Overwrite an existingAPP_KEYvalue.
.env doesn't exist, it creates the file. If APP_KEY is already set, the command warns and exits unless --force is passed.
install
Copies config and schema stubs from a@strav/* package into your project.
bun strav install social
bun strav install @strav/social # full name also works
bun strav install social --force # overwrite existing files
Options:
-f, --force— Overwrite existing files instead of skipping them.
- Resolves the package root (checks
node_modules/first, then Bun workspace resolution). - Looks for a
stubs/directory inside the package. - Copies
stubs/config/*.ts→./config/. - Copies
stubs/schemas/*.ts→./database/schemas/. - Skips files that already exist (yellow warning) unless
--forceis passed.
@strav/* package can ship stubs by including a stubs/ directory with config/ and/or schemas/ subdirectories. No manifest or registration is needed.
seed
Seeds the database with records using seeder classes fromdatabase/seeders/.
bun strav seed
bun strav seed --class UserSeeder
bun strav seed --fresh
Options:
-c, --class <name>— Run a specific seeder instead of the defaultDatabaseSeeder.--fresh— Drop all tables and re-migrate before seeding (requiresAPP_ENV=local).
- Bootstraps config, database, and wires the ORM.
- If
--fresh, runs the fullfreshpipeline (without the interactive challenge). - Resolves the seeder file (default:
database/seeders/database_seeder.ts). - Instantiates and runs the seeder.
DatabaseSeeder, which typically chains sub-seeders via this.call(). See the Database guide for full documentation.
generate:seeder
Scaffolds a database seeder class.
bun strav generate:seeder DatabaseSeeder
bun strav generate:seeder UserSeeder
bun strav generate:seeder User # also works — "Seeder" suffix is added
Options:
-f, --force— Overwrite an existing file.
database/seeders/<snake_case>_seeder.ts with a Seeder subclass skeleton.
queue:work
Start a worker process to pick up and run queued jobs.
bun strav queue:work
bun strav queue:work --queue emails --sleep 500
Options:
--queue <name>— Queue to process (default:'default').--sleep <ms>— Poll interval in milliseconds (default:1000).
Press Ctrl+C to stop the worker gracefully (finishes current job before exiting).
queue:retry
Move failed jobs back to the queue for reprocessing.
bun strav queue:retry
bun strav queue:retry --queue emails
Options:
--queue <name>— Only retry failed jobs from this queue.
queue:flush
Delete pending jobs from a queue.
bun strav queue:flush
bun strav queue:flush --queue emails
bun strav queue:flush --failed
Options:
--queue <name>— Queue to flush (default:'default').--failed— Also clear failed jobs.
Custom commands
Create your own CLI commands by adding.ts files to a commands/ directory at the project root. Each file must export a register(program) function:
// commands/deploy.ts
import type { Command } from 'commander'
export function register(program: Command): void {
program
.command('deploy')
.description('Deploy the application')
.option('-e, --env <environment>', 'Target environment', 'production')
.action(async ({ env }) => {
console.log(`Deploying to ${env}...`)
// your deployment logic
})
}
bun strav deploy --env staging
Commands are auto-discovered on startup — no registration needed.
Package commands
Installed@strav/* packages can provide their own CLI commands. A package declares its commands directory in package.json:
{
"name": "@strav/search",
"strav": {
"commands": "src/commands"
}
}
Each .ts file in that directory must export a register(program) function, following the same convention as user commands. The CLI discovers these automatically from node_modules/ and Bun workspace packages.
For example, @strav/search provides search:import and search:flush commands. See the Search guide for details.
Bootstrap
CLI commands that need a database connection use a shared bootstrap function:
import { bootstrap, shutdown } from '@strav/cli'
export function register(program: Command): void {
program.command('my:command').action(async () => {
let db
try {
const { db: database, config, registry, introspector } = await bootstrap()
db = database
// ... command logic ...
} finally {
if (db) await shutdown(db)
}
})
}
The bootstrap:
- Loads configuration from
./config. - Connects to the database.
- Discovers and validates schemas.
- Creates the database introspector.
Typical workflow
# 1. Define or modify schemas in database/schemas/
# 2. Compare against the database
bun strav compare
# 3. Generate migration files
bun strav generate:migration -m "add teams"
# 4. Apply the migration
bun strav migrate
# 5. Regenerate model classes
bun strav generate:models
# 6. Generate the application layer (services, controllers, policies, validators, events)
bun strav generate:api
# 7. Seed dev data (optional)
bun strav seed
# Full reset: drop + migrate + seed in one command
bun strav seed --fresh