docs/database/migrations.md
Drizzle Kit generates SQL migrations by diffing your TypeScript schema against the latest snapshot. Migration files live in db/migrations/ alongside a journal that tracks applied versions.
1. Edit the schema in db/schema/.
2. Generate a migration:
bun db:generate
This produces a numbered SQL file (e.g., 0001_add_product_table.sql) in db/migrations/.
3. Review the generated SQL. Drizzle Kit's output is generally correct, but always check for destructive operations – column drops, type changes, or data loss.
4. Apply the migration:
bun db:migrate
5. Verify in Drizzle Studio:
bun db:studio
| Command | What it does | Use when |
|---|---|---|
bun db:migrate | Applies pending migration files in order | Production, staging, shared databases |
bun db:push | Syncs schema directly, no migration files | Local development, rapid prototyping |
push is faster during development since it skips migration file generation. Switch to migrate when you need reproducible, reviewable changes.
Append :staging or :prod to run against other databases:
bun db:migrate:staging
bun db:migrate:prod
These set ENVIRONMENT internally, which controls which .env.{env}.local file is loaded. Double-check the target before running migrations against production.
If schema files and migration snapshots diverge (e.g., after a manual DB change or a merge conflict), run:
bun db:check
This reports discrepancies between your TypeScript schema and the migration history. Resolve by either updating the schema to match or generating a new migration to cover the gap.
bun db:generate --name add-product-table produces clearer filenames than auto-numbered defaults.db:generate writes SQL to disk. Read the file before running db:migrate.