Getting started
Define your schema
Create a
.schema.ts file with your table definitions using the d builder. See the schema
guide for details.Start the dev server
Run
vertz dev. The dev server watches your schema files and applies migrations automatically
when you save.Command comparison
| Command | Creates migration file? | Applies to DB? | Use when |
|---|---|---|---|
vertz dev | No | Yes (auto) | Local development — schema changes apply on save |
vertz db push | No | Yes | Quick one-off schema sync without a migration file |
vertz db migrate | Yes | Yes | Generating a reviewable migration file for production |
vertz db deploy | No | Yes (pending only) | Production deployments — applies committed migration files |
vertz db pull | No | No | Generate a schema file from an existing database |
autoMigrate() | No | Yes | Programmatic dev setup (test suites, scripts). SQLite only. |
vertz dev— the default for local development. No commands to remember.vertz db push— useful when you want to apply changes outside the dev server without generating a migration file (e.g., CI test databases).vertz db migrate— generates a numbered.sqlfile in your migrations directory and applies it. Commit this file to version control.vertz db deploy— reads migration files from disk and applies any that haven’t been applied yet. Never generates new files. Safe for production.vertz db pull— connects to an existing database and generates a TypeScript schema file. See the introspection guide.autoMigrate()— a programmatic API for test setup or custom scripts. It diffs the schema snapshot and applies changes directly. Currently supports SQLite only — Postgres users should usevertz db pushormigrateDev()instead.
File structure
After runningvertz db migrate, your project will have:
| File | Purpose |
|---|---|
migrations/*.sql | Numbered migration files containing DDL statements. Commit these. |
migrations/_journal.json | Tracks which migrations exist, their checksums, and creation timestamps. Commit this. |
migrations/_snapshot.json | The current schema state used for diffing. Commit this. |
./migrations/ and can be changed via migrationsDir in vertz.config.ts.
Development workflow
Duringvertz dev, schema changes are detected and applied automatically:
- Detects
.schema.tsfile changes - Diffs the current schema against the last snapshot
- Generates and applies the necessary SQL
- Warns on destructive changes (table or column drops)
- Updates the snapshot
Manual commands
If you need to run migrations outside the dev server:Production workflow
For production deployments, use explicit migration files:vertz db deploy only applies existing migration files — it never generates new ones. This ensures production databases only receive reviewed, committed migrations.
Check migration status
Baseline
For existing databases, create a baseline migration that represents the current state:Programmatic API
For custom tooling or test setup:RLS policy migrations
If you use RLS policy generation from the codegen system, the migration pipeline can include RLS changes alongside schema changes. When you passrlsPolicies to migrateDev(), it diffs the current RLS state against the previous snapshot and appends the necessary SQL:
- Schema DDL changes (table/column modifications)
ALTER TABLE ... ENABLE ROW LEVEL SECURITYfor new RLS tablesDROP POLICYfor removed or changed policiesCREATE POLICYfor new or changed policiesALTER TABLE ... DISABLE ROW LEVEL SECURITYfor tables that no longer have policies
Setting session variables
RLS policies reference PostgreSQL session variables (app.user_id, app.tenant_id) via current_setting(). These must be set per-request within a transaction using SET LOCAL:
SET LOCAL scopes the variables to the current transaction — they’re automatically cleared on commit or rollback. The framework’s entity CRUD pipeline sets these automatically when RLS policies are present.
Troubleshooting
Snapshot out of sync
Symptom:vertz db migrate generates unexpected changes (re-adding columns that already exist, or dropping columns you didn’t remove).
Cause: The _snapshot.json file doesn’t match the actual database state. This can happen if you applied schema changes manually or edited the database outside the migration system.
Fix:
- Run
vertz db statusto see what the system thinks the current state is. - If the database is correct and the snapshot is wrong, run
vertz db pushto sync the snapshot to match your current schema, then runvertz db migrateto generate a clean migration. - If the database is wrong, run
vertz db reset(development only) to rebuild from migration files.
Migration fails to apply
Symptom:vertz db deploy or vertz db migrate fails with a SQL error.
Fix:
- Read the error — it usually points to a specific SQL statement (e.g., column already exists, constraint violation).
- If the migration was partially applied, check
vertz db statusto see which migrations succeeded. - Fix the failing migration SQL file manually, then re-run
vertz db deploy. - If the database is in an inconsistent state in development,
vertz db resetwill drop everything and re-apply all migrations from scratch.
Concurrent schema edits
Symptom: Two developers edit the schema at the same time and both runvertz db migrate. The second migration may conflict with the first.
Fix:
- The journal system detects sequence number collisions. If two migrations share the same number,
vertz db migratewill warn you. - Pull the latest migrations from version control, resolve any conflicts in the SQL files and
_journal.json, then re-runvertz db migrate.
autoMigrate not available for Postgres
autoMigrate() only supports SQLite. If you need programmatic migration for Postgres in test setup or scripts, use migrateDev() or push() from vertz/db instead: