Schema Migrations with Drizzle Kit
As applications evolve, database schemas must change to support new features, fix issues, or optimize performance.
Context
As applications evolve, database schemas must change to support new features, fix issues, or optimize performance. These changes need to be tracked in version control, reproducible across development and production environments, applied safely without data loss, and automated within CI/CD pipelines. Without proper migration management, schema drift between environments, lost data during schema changes, and broken deployments due to schema-code mismatches become serious risks.
For an application using Drizzle ORM for schema definition and SQLite as the embedded database, the migration tool must work seamlessly with Drizzle schema files and generate SQL migrations automatically from schema diffs.
Decision
Drizzle Kit manages all schema migrations. SQL migration files are auto-generated by comparing Drizzle schema definitions against the current database state, and these files are tracked in version control. Migration files must never be manually edited unless absolutely necessary.
The migration workflow is:
- Modify Drizzle schema files in TypeScript.
- Run Drizzle Kit's
generatecommand to create a SQL migration file. - Review the generated SQL for correctness.
- Run Drizzle Kit's
migratecommand to apply the migration. - Commit schema changes and migration files together in the same commit.
A drizzle.config.ts file must exist in each datamodel package to configure the schema source, migration output directory, and database dialect.
Do's and Don'ts
Do
- Generate migrations using Drizzle Kit's
generatecommand after every schema change. - Review generated migration SQL before applying it.
- Test migrations on sample data before applying to production.
- Commit migration files with schema changes in the same commit.
- Apply migrations in development, staging, and production in the same order.
- Back up databases before applying migrations in production.
- Document complex migrations with comments in the SQL.
Don't
- Manually edit generated migration files unless absolutely necessary.
- Skip migrations or apply them out of order.
- Delete migration files after they have been applied.
- Modify schema files without generating corresponding migrations.
- Apply migrations directly with SQL tools instead of Drizzle Kit.
- Commit schema changes without their migrations.
- Apply untested migrations to production.
Consequences
Positive
- Automatic generation: Drizzle Kit detects schema changes and generates correct SQL.
- Version controlled: all migrations are tracked in Git alongside the schema.
- Reproducible: same migrations apply consistently across all environments.
- Type-safe: schema changes are validated by TypeScript before migration generation.
- Integrated: works seamlessly with Drizzle ORM schema definitions.
- Safe: SQLite transactions ensure atomic migration application.
Negative
- Generated SQL should always be reviewed, adding a manual step to the workflow.
- Some complex schema changes (e.g., column renames in SQLite) may require manual SQL.
- Migration files accumulate over time, increasing repository size.
- Concurrent schema changes by multiple developers may produce conflicting migrations.