Getting Started
Database Drivers
Schema Integrations
Seed Generators
Utilities and Testing
The following files were used as context for generating this wiki page:
The "Kit Overview" encompasses the core logic responsible for database introspection, snapshot management, and the generation of migration SQL. Its primary role is to bridge the gap between application-defined schemas and the actual state of a target database, facilitating the transition between declarative state definitions (snapshots) and imperative schema changes (migrations).
The system addresses the fundamental complexity of evolving database schemas, such as handling renames, moved objects, and attribute modifications that cannot be inferred from simple object comparisons alone. It leverages a "snapshot differ" architecture, where previous and current schema states are compared, and resolutions for ambiguities (like table or column renames) are provided via CLI prompts or automated resolvers.
At its architecture's center is a robust transformation pipeline: it converts schema differences into intermediate JSON-based statements, which are then serialized into vendor-specific SQL. This decoupling ensures that the logic for identifying changes is shared across databases (PostgreSQL, MySQL, SQLite, SingleStore), while the final SQL emission remains isolated in specific generators.
The core engine for detecting schema changes resides in snapshotsDiffer.ts. It performs a multi-stage comparison between json1 (previous snapshot) and json2 (current schema). The differ functions (diffSchemasOrTables, diffColumns, diffPolicies) compute the delta by identifying additions, deletions, and potential renames.
The system utilizes copy() to create working snapshots (schemasPatchedSnap1, tablesPatchedSnap1) that are progressively updated as renames are resolved. This allows the differ to operate on "patched" states where, for instance, a renamed table is treated as a single entity rather than a deletion and an addition.
Important
The differ does not assume names are immutable. It explicitly delegates rename/move resolution to injected resolver functions (e.g., tablesResolver), which can trigger user interaction or heuristics to map "deleted" objects to "created" objects.
Sources: drizzle-kit/src/snapshotsDiffer.ts:603-1234
To accurately reflect changes in the database, the differ must maintain consistency across nested object structures. When a schema or table is moved or renamed, the system performs a sequence of pointer updates:
schemaChangeFor maps the current object to its new schema location based on rename resolution.enumsResolver and sequencesResolver handle moving/renaming enums and sequences, which are then propagated through to dependent columns using columnTypesChangeMap.mapEntries and mapValues are used to reconstruct the tablesPatchedSnap1 state, which serves as the "corrected" baseline for the final applyJsonDiff call.This state-patching flow ensures that by the time applyJsonDiff is invoked, the "old" snapshot and "new" snapshot are aligned by name and schema, leaving only additive, subtractive, or attribute-level changes to be computed.
Sources: drizzle-kit/src/snapshotsDiffer.ts:614-709
Once the final diff is calculated, the Kit converts these deltas into a unified format (JsonStatement[]). The pipeline follows a strict execution order to prevent dependency violations (e.g., dropping a table that is still referenced by a foreign key):
alter_table_alter_column_set_type) are generated.The system uses specific prepare* functions (e.g., preparePgCreateTableJson, prepareAddColumns) which return these JsonStatement objects.
// Example: Simplified dependency-aware statement accumulation
jsonStatements.push(...jsonDropIndexesForAllAlteredTables);
jsonStatements.push(...jsonDeletedCompositePKs);
jsonStatements.push(...jsonTableAlternations);
jsonStatements.push(...jsonAddedCompositePKs);
jsonStatements.push(...jsonAddColumnsStatemets);Sources: drizzle-kit/src/snapshotsDiffer.ts:1973-2018
Introspection, specifically for PostgreSQL, transforms database metadata into Drizzle-compatible TypeScript code. It handles complex PostgreSQL features such as:
generateIdentityParams, which differentiates between generatedAlwaysAsIdentity and generatedByDefaultAsIdentity.schema.enums and enumTypes set to identify which types require pgEnum declarations.mapColumnDefault and mapDefault determine whether a default value is a literal or an SQL expression requiring sql template tags.The system uses withCasing to translate database column names to their requested casing (camel vs. preserve).
Caution
If a type fails to parse (e.g., an unknown geometry type), the generator will emit an unknown() call as a fallback to avoid crashing, which allows the developer to manually inspect the generated code.
Sources: drizzle-kit/src/introspect-pg.ts:277-302, drizzle-kit/src/introspect-pg.ts:1064-1101
The following diagram illustrates the interaction between snapshots, resolvers, and final SQL generation.
Sources: drizzle-kit/src/snapshotsDiffer.ts:559-602
Sources: drizzle-kit/src/snapshotsDiffer.ts:1948-2022