drizzle-orm — releases
Latest 20 GitHub releases for drizzle-team/drizzle-orm. Auto-mirrored by playbooks/local/autodocgen.yml.
[!info] Pinned in BreeZ-CF:
0.45.2· upstream latest:v1.0.0-beta.22.
v1.0.0-beta.22 · v1.0.0-beta.22
2026-04-16 · by @AndriiSherman · prerelease
Bug fixed
- drizzle-kit generate fails to generate correct migrations.js file on Windows
- [BUG]: MSSQL real() column returns imprecise float64 values -- missing mapFromDriverValue
- Object key collision
- [BUG]:beta20 Migration to Cloudflare D1 fails
- [BUG]: drizzle-kit migrate: migration SQL failures exit with code 1 but print no error (MigrateProgress hides rejection)
- [BUG]: MS SQL Filtered Index - Drizzle Kit incorrectly generates fully qualified column name in WHERE clause
- [BUG]: [Drizzle-kit][Pg] Altering a UNIQUE constraint: generated SQL ignores the new changes
-
[BUG]: Non-commutative migration false positive: create_index commutativity check ignores table name
-
Commutativity checks were updated for PostgreSQL and MySQL. Before,
create_indexstatements could be reported as non-commutative even when they targeted different tables, and--ignore-conflictscould still collapse multi-parent history down to a single parent. Now index/table/schema footprints are resolved more accurately, unrelated index branches are accepted, and--ignore-conflictspreserves all open leaf parents for the next migration -
fix: mark mssql and @types/mssql as optional peer dependencies
1.0.0-beta.21 · v1.0.0-beta.21
2026-04-14 · by @AndriiSherman · prerelease More fixes for the drizzle-kit migration process and commutativity checks
- Adding a value to a PostgreSQL enum will no longer be treated as commutative
- Enum values added in different leaves will now be merged properly
1.0.0-beta.20 · v1.0.0-beta.20
2026-03-27 · by @AndriiSherman · prerelease
- Fixed sql.identifier(), sql.as() escaping issues. Previously all the values passed to this functions were not properly escaped
causing a possible SQL Injection (CWE-89) vulnerability
Thanks to @EthanKim88, @0x90sh and @wgoodall01 for reaching out to us with a reproduction and suggested fix
0.45.2 · 0.45.2
2026-03-27 · by @github-actions[bot]
- Fixed sql.identifier(), sql.as() escaping issues. Previously all the values passed to this functions were not properly escaped
causing a possible SQL Injection (CWE-89) vulnerability
Thanks to @EthanKim88, @0x90sh and @wgoodall01 for reaching out to us with a reproduction and suggested fix
v1.0.0-beta.19 · v1.0.0-beta.19
2026-03-23 · by @AndriiSherman · prerelease
New Features
sqlcommenter support for PostgreSQL and MySQL
You can now add custom tags to the query. These tags will be appended to the end of each query, helping the database add metadata/tags to it. This will be especially useful with PlanetScale’s new Database Traffic Control feature
// raw string support
db.select().from().comment("key='val'");
db.select().from().comment("my_first_tag");
// developer friendly dedicated to tags
db.select().from().comment({ key: 'val' });
Example:
db.select().from(comments).comment({ priority: 'high', category: "analytics" });
select "id", "name" from "comments" /*priority='high',category='analytics'*/
The only limitation is that you can't use comments with a prepared statement:
// can't be used
const p = db.select().from().prepare();
// ❌
p.comment({ key: 'val' }).execute();
Bug fixes
- Fixed error message for the defineRelations function
- [BUG]: drizzle-kit push attempts to drop policies in excluded schemas (e.g. cron) despite schemaFilter: ["public"]
- [BUG]: error attempting to drizzle-kit migrate table with char array field generated using drizzle-kit generate
- [BUG]: Ignore Vim *.swp files in drizzle-kit generate
- [BUG]: drizzle-kit pull outputs access method name instead of operator class for ivfflat indexes
- [BUG]: drizzle-kit pull generates not enough data provided to build the relation
- drizzle-kit push fails with Turso/libSQL on table recreation: "cannot commit - no transaction is active"
- [BUG]: Cannot read properties of undefined (reading 'requestLayout') when running drizzle-kit introspect (MySQL)
- [BUG (beta)]: RDS Data API pulling schema error
- [BUG]: drizzle-kit commutative migrations takes only last leaf migration into account
Updates
-
Updated
migrate()function for mysql dialect to correctly manage multiple databases -
The behavior for reading schema files has been updated. From now only files with the following extensions will be processed:
.js.mjs.cjs.jsx.ts.mts.cts.tsx. All other file types will be ignored
v1.0.0-beta.18 · v1.0.0-beta.18
2026-03-17 · by @AndriiSherman · prerelease
New driver support for kit and studio
You can now use the node:sqlite driver to run migrations and browse Drizzle Studio. If node:sqlite is available at runtime, we will automatically detect it and use it.
Fixes
- resolved tsconfig path aliases in drizzle-kit loader using get-tsconfig + jiti alias mapping
- added fixtures and tests covering wildcard and non-wildcard path aliases
- ensured schema load succeeds for alias imports
- Updated to
hanji@0.0.8- native bunstringWidth,stripANSIsupport, errors for non-TTY environments - [BUG]: drizzle-kit@1.0.0-beta.13 regression in module resolution
- [BUG]: drizzle-kit does not support node:sqlite
drizzle-kit@0.31.10 · drizzle-kit@0.31.10
2026-03-17 · by @github-actions[bot]
- Updated to hanji@0.0.8 - native bun stringWidth, stripANSI support, errors for non-TTY environments
- We've migrated away from esbuild-register to tsx loader, it will now allow to use drizzle-kit seamlessly with both ESM and CJS modules
- We've also added native Bun and Deno launch support, which will not trigger tsx loader and utilise native bun and deno imports capabilities and faster startup times
v1.0.0-beta.17 · v1.0.0-beta.17
2026-03-11 · by @AndriiSherman · prerelease
New SQLite driver node-sqlite
Usage example:
```typescript copy import { drizzle } from 'drizzle-orm/node-sqlite';
const db = drizzle("sqlite.db");
const result = db.select().from(...);
If you need to provide your existing driver:
```typescript copy
import { drizzle } from 'drizzle-orm/node-sqlite';
import { DatabaseSync } from 'node:sqlite';
const sqlite = new DatabaseSync('sqlite.db');
const db = drizzle({ client: sqlite });
const result = db.select().from(...);
Fixes
We added a few checks to the migration upgrade logic introduced in beta.16. Now, when your migrations table is upgraded, we double-check that all entities in the table have been updated. If any are missing, we prompt you to pull all migrations into your environment so that we can properly update the drizzle_migrations table
v1.0.0-beta.16 · v1.0.0-beta.16
2026-03-05 · by @AndriiSherman · prerelease
Drizzle ORM beta.16 updates
We've fixed a regression in migrations introduced in beta.13 that persisted through beta.15, and used the opportunity to significantly improve the entire migration infrastructure going forward.
After receiving github issue, we focused on not just fixing the symptoms but rethinking how migrations are tracked, validated, and applied. As we always do with Drizzle we went deeper and redesigned the underlying architecture so it can be stable for all future changes, additions, and edge cases
We went through how we check migrations, how we store them, and how we help developers keep their migration flow reliable. After several iterations of rewriting the migrate function in both ORM and Kit, adding migration table versioning, and building a new commutativity check system: here's what changed and why.
What happened in beta.12–beta.15 and what caused the issue
On latest (pre-beta) versions, the migrations folder used a journal-based structure. A meta/_journal.json file stored a timestamp for each migration in milliseconds. That same millis value was stored in the database's created_at column and used to determine which migrations had been applied. Because the journal enforced ordering, we could simply fetch the last applied migration from the database and apply everything after it.
With the new v3 folder structure (introduced in beta), each migration lives in its own folder named <YYYYMMDDHHmmss>_<name>. This format only has second precision. The new structure also intentionally allows out-of-order migrations (as it should for team workflows), so we switched to reading all migrations from the database and comparing against all local migrations.
The problem appeared after drizzle-kit up converted the old journal structure to v3 folders. It mapped millis timestamps to the YYYYMMDDHHmmss_name format, stripping away the millisecond precision. So when the new migration checker compared what was in the database (millis) to what was on disk (seconds), nothing matched causing migrations to be re-applied on every run.
This only affected beta users who upgraded from the journal-based format. Users on latest were not impacted.
How we fixed it
1. Versioned migration table
Version 0 (old schema):
| Column | Type |
|---|---|
| id | serial |
| hash | text |
| created_at | bigint (millis) |
Version 1 (new schema):
| Column | Type | |
|---|---| ---|
| id | serial |
| hash | text |
| created_at | bigint | (legacy) |
| name | text |
| applied_at | timestamp |
The name column stores the full folder name of the migration (e.g. 20250220153045_brave_wolverine). The applied_at column records when the migration was actually executed. For pre-existing migrations that were backfilled during upgrade, applied_at is set to NULL to distinguish them from newly applied ones.
This versioning system means we can add more fields in the future (like migration state for rollbacks) without any disruption for developers
2. Matching by folder name instead of timestamps
All migrations are now checked against the full folder name: the combination of a 14-digit UTC timestamp and a name suffix (random or custom). Even if two migrations are generated within the same second, the name suffix guarantees uniqueness.
The detection logic is simple: build a set of name values from the database, filter local migrations whose name isn't in that set, and apply those. No more timestamp arithmetic, no more precision mismatches.
3. Automatic upgrade with smart backfilling
When beta.16 detects a version_0 table, it adds the new columns and backfills the name for each existing row using a multi-step matching strategy:
- Millis match: truncate the stored millis to seconds and match against local migration folder timestamps
- Hash tiebreaker: if multiple migrations share the same second, use the SQL hash to pick the right one
- Hash-only fallback: if millis matching fails entirely, fall back to matching by hash alone
This means the upgrade handles all edge cases: normal single-developer projects, teams with closely-timed migrations, and even cases where the old journal data doesn't perfectly align with the new folder names.
4. New commutativity checks (drizzle-kit check)
When working in teams, multiple developers may generate migrations from the same base schema on different branches. These migrations can conflict in non-obvious ways, for example, two branches both altering a column to the same table, or one renaming a table that another is altering.
We built a new drizzle-kit check command that detects these non-commutative migrations. It works by:
- Building a DAG (directed acyclic graph) from snapshot
prevIdsto understand the branch structure - Finding fork points where branches diverged
- Computing the DDL diff from the parent snapshot to each branch leaf
- Checking for conflicting operations using a comprehensive footprint map that knows which DDL statement types can interfere with each other
This is available for PostgreSQL and MySQL today. If conflicts are found, the report tells you exactly which migrations on which branches are incompatible and what statements are conflicting.
The new folder structure also changed snapshot metadata from prevId: string to prevIds: string[], enabling proper DAG representation of migration history across branches.
Upgrading to beta.16
The upgrade is automatic. When you run migrate for the first time on beta.16:
- Drizzle detects your migration table version
- If it's
version_0, it adds the new columns and backfillsnamefrom your local migration files - All future migrations are tracked by name
- No manual steps required
If you're also upgrading your migration folder structure from the old journal format, run drizzle-kit up first to convert to the v3 folder layout, then migrate will handle the rest.
Upgrading to beta.16 is not fixing my problem
If you're still hitting migration issues after upgrading, please reach out to us directly - drop a message in Discord or open a GitHub issue with your migration folder structure and the contents of your migrations table. We'll help you sort it out.
drizzle-kit@0.31.9 · drizzle-kit@0.31.9
2026-02-09 · by @github-actions[bot] - drizzle-kit api improvements for D1 connections
v1.0.0-beta.15 · v1.0.0-beta.15
2026-02-05 · by @AndriiSherman · prerelease
Changes
We've stopped maintaining separate validator packages (e.g., drizzle-zod, drizzle-valibot) and moved them into the drizzle-orm repo. This consolidates everything into a single package and eliminates the need to manage separate peer dependencies and versioning.
All packages are now available via drizzle-orm imports:
drizzle-zod->drizzle-orm/zoddrizzle-valibot->drizzle-orm/valibotdrizzle-typebox->drizzle-orm/typebox-legacy(using@sinclair/typebox)drizzle-typebox->drizzle-orm/typebox(usingtypebox)drizzle-arktype->drizzle-orm/arktype
You can still use the old packages, but we recommend removing them and importing directly from drizzle-orm. There should be no breaking changes and a simple import change should work
New Features
New validation package is available: drizzle-orm/effect-schema
import * as p from 'drizzle-orm/pg-core';
import { createInsertSchema, createSelectSchema, createUpdateSchema } from 'drizzle-orm/effect-schema';
import { Schema } from 'effect';
const users = p.pgTable('users', {
id: p.serial().primaryKey(),
name: p.text().notNull(),
email: p.text().notNull(),
role: p.text({ enum: ['admin', 'user'] }).notNull(),
createdAt: p.timestamp('created_at').notNull().defaultNow(),
});
// Schema for inserting a user - can be used to validate API requests
const UserInsert = createInsertSchema(users);
// Schema for updating a user - can be used to validate API requests
const UserUpdate = createUpdateSchema(users);
// Schema for selecting a user - can be used to validate API responses
const UserSelect = createSelectSchema(users);
// Overriding the fields
const UserInsert = createInsertSchema(users, {
role: Schema.String,
});
// Refining the fields - useful if you want to change the fields before they become nullable/optional in the final schema
const UserInsert = createInsertSchema(users, {
id: (schema) => schema.pipe(Schema.greaterThanOrEqualTo(0)),
role: Schema.String,
});
// Usage
const program = Effect.gen(function*() {
const parsedUser = yield* Schema.validate(UserInsert)({
name: 'John Doe',
email: 'johndoe@test.com',
role: 'admin',
});
});
Improvements
- Fixed sqlite select not allowing SQL.Aliased in
.orderBy(...),.groupBy(...)
This is now allowed:
const sq1 = db.$with('sq1').as((qb) =>
qb.select({
aliased: sql`count(*)`.mapWith(Number).as('alias'),
}).from(users)
);
const sq2 = db.$with('sq2').as((qb) =>
qb.select({
aliased: sql`sum(${users.id})`.mapWith(Number).as('alias'),
}).from(users)
);
const result = await db.with(sq1, sq2).select({
count: sq1.aliased,
sum: sq2.aliased,
}).from(sq1).crossJoin(sq2);
- Made
nameargument in.prepare(name)optional inGel,Postgres,Cockroachdialects (generated automatically if not passed)
v1.0.0-beta.14 · v1.0.0-beta.14
2026-02-04 · by @AndriiSherman · prerelease
Migrator update
The migrator now applies all changes that are missing in the database. Previously the migrator only looked for local migrations with a creation date later than the last migration applied in the database
Now it detects and applies all missing migrations
- Fixed
generateandpullcommands to display theSQL fileinstead of thefolderpath in the migration output messageYour SQL migration ➜ path
Bug fixed
- [BUG]: Cache is not invalidated after table updates
- [BUG]: Composite index with sort outputs a malformed SQL
- [BUG]: db introspection generates broken schema.ts syntax
randomproperty is set onArray.prototypewithenumerable: true- Fixed error TS7056 appearing when using "declaration": true in defineRelations with reworked PgColumns
- [BUG]: mssql transaction is not a function
-
Fixed an error when seeding a composite unique column that includes a foreign key
-
Postgres:
DROP INDEXstatement did not respect schema - Restricted usage of async functions in sync drivers' transactions
1.0.0-beta.13 · v1.0.0-beta.13
2026-02-02 · by @AndriiSherman · prerelease
Drizzle Kit updates
- Enabled top-level await in
drizzle-kit.configand schema files on Node.js by replacingrequire()withasync loadModule()usingjiti - Fixed [FEATURE]: Support Top-level await in drizzle.config.ts
- Fixed [BUG]: SyntaxError: Cannot use import statement outside a module with drizzle-kit
Drizzle Effect Postgres updates
We've updated an API and the Drizzle+Effect usage example to make it feel more native to Effect's style:
Before beta.13
import 'dotenv/config';
import { drizzle } from 'drizzle-orm/effect-postgres';
import { Effect, Redacted } from 'effect';
import { PgClient } from '@effect/sql-pg'
import { types } from 'pg';
const clientLayer = PgClient.layer({
url: Redacted.make(process.env.DATABASE_URL!);
types: {
getTypeParser: (typeId, format) => {
if ([1184, 1114, 1082, 1186, 1231, 1115, 1185, 1187, 1182].includes(typeId)) {
return (val: any) => val;
}
return types.getTypeParser(typeId, format);
},
},
});
const program = Effect.gen(function*() {
const client = yield* PgClient.PgClient;
const db = drizzle(client, { logger: true, /*...*/ });
});
await Effect.runPromise(program).pipe(Effect.provide(clientLayer));
now for beta.13+
import 'dotenv/config';
import * as PgDrizzle from 'drizzle-orm/effect-postgres';
import { PgClient } from '@effect/sql-pg';
import * as Effect from 'effect/Effect';
import * as Redacted from 'effect/Redacted';
import { sql } from 'drizzle-orm';
import { types } from 'pg';
// Configure the PgClient layer with type parsers
const PgClientLive = PgClient.layer({
url: Redacted.make(process.env.DATABASE_URL!),
types: {
getTypeParser: (typeId, format) => {
// Return raw values for date/time types to let Drizzle handle parsing
if ([1184, 1114, 1082, 1186, 1231, 1115, 1185, 1187, 1182].includes(typeId)) {
return (val: any) => val;
}
return types.getTypeParser(typeId, format);
},
},
});
const program = Effect.gen(function*() {
// Create the database with default services (no logging, no caching)
const db = yield* PgDrizzle.makeWithDefaults();
// Execute queries
const result = yield* db.execute<{ id: number }>(sql`SELECT 1 as id`);
console.log(result);
});
// Run the program with the PgClient layer
Effect.runPromise(program.pipe(Effect.provide(PgClientLive)));
import * as PgDrizzle from 'drizzle-orm/effect-postgres';
import { PgClient } from '@effect/sql-pg';
import * as Context from 'effect/Context';
import * as Effect from 'effect/Effect';
import * as Layer from 'effect/Layer';
import * as Redacted from 'effect/Redacted';
import { types } from 'pg';
import * as relations from './schema/relations';
// Configure the PgClient layer
const PgClientLive = PgClient.layer({
url: Redacted.make(process.env.DATABASE_URL!),
types: {
getTypeParser: (typeId, format) => {
if ([1184, 1114, 1082, 1186, 1231, 1115, 1185, 1187, 1182].includes(typeId)) {
return (val: any) => val;
}
return types.getTypeParser(typeId, format);
},
},
});
// Create the DB effect with default services
const dbEffect = PgDrizzle.make({ relations }).pipe(
Effect.provide(PgDrizzle.DefaultServices)
);
// Define a DB service tag for dependency injection
class DB extends Context.Tag('DB')<DB, Effect.Effect.Success<typeof dbEffect>>() {}
// Create a layer that provides the DB service
const DBLive = Layer.effect(
DB,
Effect.gen(function*() {
return yield* dbEffect;
}),
);
// Compose all layers together
const AppLive = Layer.provideMerge(DBLive, PgClientLive);
// Use the DB service in your application
const program = Effect.gen(function*() {
const db = yield* DB;
const users = yield* db.select().from(usersTable);
return users;
});
// Run with all dependencies provided
Effect.runPromise(program.pipe(Effect.provide(AppLive)));
Native Effect Logger integration
By default, makeWithDefaults() uses a no-op logger (no logging). You can enable logging by providing a different EffectLogger implementation:
import * as PgDrizzle from 'drizzle-orm/effect-postgres';
import { EffectLogger } from 'drizzle-orm/effect-postgres';
import * as Effect from 'effect/Effect';
const program = Effect.gen(function*() {
const db = yield* PgDrizzle.make({ /* schema, relations, casing */ }).pipe(
// Enable Effect-based logging (uses Effect.log with annotations)
Effect.provide(EffectLogger.layer),
// Provide remaining default services (cache)
Effect.provide(PgDrizzle.DefaultServices),
);
const users = yield* db.select().from(usersTable);
return users;
});
Available logger options:
EffectLogger.Default- No-op logger (no logging occurs) - this is the defaultEffectLogger.layer- Logs queries using Effect’s Effect.log() with annotations for query SQL and parameters. Integrates with Effect’s logging infrastructure.EffectLogger.fromDrizzle(logger)- Wraps a Drizzle Logger instance for use with EffectEffectLogger.layerFromDrizzle(logger)- Creates an Effect Layer from a Drizzle logger
When using EffectLogger.layer, queries are logged via Effect’s logging system. You can configure the output format by providing a different Effect logger layer (e.g., Logger.pretty for development, Logger.json for production).
Using a Drizzle logger:
import * as PgDrizzle from 'drizzle-orm/effect-postgres';
import { EffectLogger } from 'drizzle-orm/effect-postgres';
import * as Effect from 'effect/Effect';
import { DefaultLogger } from 'drizzle-orm';
const program = Effect.gen(function*() {
const db = yield* PgDrizzle.make({ /* schema, relations, casing */ }).pipe(
// Use a Drizzle logger wrapped for Effect
Effect.provide(EffectLogger.layerFromDrizzle(new DefaultLogger())),
// Provide remaining default services (cache)
Effect.provide(PgDrizzle.DefaultServices),
);
const users = yield* db.select().from(usersTable);
return users;
});
Effect Cache configuration
Similarly, you can provide a custom cache implementation:
import * as PgDrizzle from 'drizzle-orm/effect-postgres';
import { EffectLogger } from 'drizzle-orm/effect-postgres';
import { EffectCache } from 'drizzle-orm/cache/core/cache-effect';
import * as Effect from 'effect/Effect';
import { MyCustomCache } from './cache';
const program = Effect.gen(function*() {
const db = yield* PgDrizzle.make({ /* schema, relations, casing */ }).pipe(
// Provide a custom cache wrapped for Effect
Effect.provide(EffectCache.layerFromDrizzle(new MyCustomCache())),
// Provide remaining default services (logger)
Effect.provide(PgDrizzle.DefaultServices),
);
const users = yield* db.select().from(usersTable);
return users;
});
1.0.0-beta.12 · v1.0.0-beta.12
2026-01-22 · by @AndriiSherman · prerelease
Breaking changes
- .generatedAlwaysAs() know only accepts sql`` and () => sql``
Improvements
Postgresql dialect now have extra schema errors in ts files on generate and push commands:
- table_name_duplicate - duplicate table name across schema
- column_name_duplicate - duplicate column name across table
- enum_name_duplicate - duplicate enum name across schema
- enum_values_duplicate - duplicate values inside enum
- privilege_duplicate - duplicate privilege name
- role_duplicate - duplicate role name
- schema_name_duplicate - duplicate schema name
SQLite dialect now have extra schema errors in ts files on generate and push commands:
- conflict_column - duplicate column name across table
- conflict_fk - duplicate fk name
- conflict_index - duplicate index name
- conflict_pk - duplicate pk name
- table_no_columns - table has no columns
Bug fixes
- [BUG]: drizzle-kit generate silently exits with code 1
- [BUG]:Unable to resolve module node:crypto
- [BUG]: The package at "node_modules/.bun/drizzle-orm@1.0.0-beta.2-6565b14+35e4bda3077d71da/node_modules/drizzle-orm/migrator.js" attempted to import the Node standard library module "node:crypto". It failed because the native React runtime does not include the Node standard library.
- [BUG]: Problem with backslash in check constraint
- [BUG]: drizzle-kit up throws error "Cannot convert undefined or null to object"
- Fixed
bun-sqlitedb.get(...)returning data in array mode instead of object mode - Fixed
effect-postgresdriver ignoring cache config option - [BUG]: Types do not allow for placeholder usage in onConflictDoUpdate.set
- [BUG]: alias doesn't work with views (Postgres)
- [BUG]:
select()...for("...", { of: table })uses qualified name of table - [BUG]: arrayContains() generates incorrect SQL parameters for PostgreSQL, leading to operator does not exist: text[] @> record error
- [BUG]: Params not inlined for single-table selects
v1.0.0-beta.9 · v1.0.0-beta.9
2026-01-15 · by @AndriiSherman · prerelease
- Drizzle now has native @effect/sql-pg driver support
That is a big milestone for Drizzle. We did rework our query builder chain and it supports both EffectLike and PromiseLike flows, we will gather feedback from the community and ship other dialects support
- We did also rework(simplified) PgColumn type chain, it's now mostly decoupled from other dialects, it now has better type performance and simpler declaration chain. We did remove PgArray column recursive wrapper, every PgColumn now has dimensions property both in runtime and type chain for external usage like validation packages
- We have 1 breaking API change too, postgres .array() is now not chainable, if you want to have multidimensional array it's now .array('[][]'),.array('[][][]'), etc.
- Fixed lack of query result recalculation on pg dynamic update with joins
- Switched MySQL2 default client from CallbackPool to Pool
- We've migrated away from
esbuild-registertotsxloader, it will now allow to use drizzle-kit seamlessly with both ESM and CJS modules - We've also added native Bun and Deno launch support, which will not trigger tsx loader and utilise native bun and deno imports capabilities and faster startup times
v1.0.0-beta.11 · v1.0.0-beta.11
2026-01-15 · by @AndriiSherman · prerelease
- Defaulted PgTimestampString timezone offset to be +00 when value gets returned as Date instance
- Pg: Cache is now used only when explicitly defined. In recent beta versions caching was still applied even when no cache was configured
- Separated date and int-exclusive column methods from common pg builder (separeted .defaultNow(), .generatedAlwaysAsIdentity(), .generatedByDefaultAsIdentity())
Bug fixes
- [BUG]:drizzle-kit pull generates incorrect schema for functional/computed index
- [BUG]: drizzle-kit pull generates invalid code for MySQL datetime with DEFAULT CURRENT_TIMESTAMP ON UPDATE
- [BUG]: Drizzle-kit - push tries to delete non-public schemas by default (pscale_extensions)
-
Commutativity for
MySQLnow(N)andCURRENT_TIMESTAMP(N)
MySQL pull command:
- Creation of a primary key when a column had only UNIQUE and NOT NULL
- varbinary() config was ignored in a ts schema file
- Foreign key column duplication when constraint names matched across multiple databases
- Inconsistent casing between schema.ts and relations.ts
- Cyclic references are generated as inline .references((): AnyMySqlColumn => ...) to avoid type errors for single-column references
Common:
- Relation name collisions with column names during introspection. If a relation name collides with a column name - the relation is renamed to <name>Relation
v1.0.0-beta.8 · v1.0.0-beta.8
2025-12-31 · by @AndriiSherman · prerelease
drizzle-seed updates
Bug fixes
- [BUG]: drizzle seed doesn't work with libSQL
- [BUG]: Seed UUIDs not compatible with Zod/v4
- [BUG]: drizzle seed generates invalid input value (number) for enum strings (pg)
- [BUG]: drizzle seed breaks serial sequence sync with Postgres serial type
Features
ignore column in refinements
Now you can let drizzle-seed know if you want to ignore column during seeding.
// schema.ts
import { integer, pgTable, text } from "drizzle-orm/pg-core";
export const users = pgTable("users", {
id: integer().primaryKey(),
name: text().notNull(),
age: integer(),
photo: text(),
});
// index.ts
import { drizzle } from "drizzle-orm/node-postgres";
import { seed } from "drizzle-seed";
import * as schema from "./schema.ts";
async function main() {
const db = drizzle(process.env["DATABASE_URL"]!);
await seed(db, schema).refine((f) => ({
users: {
count: 5,
columns: {
name: f.fullName(),
photo: false, // the photo column will not be seeded, allowing the database to use its default value.
},
},
}));
}
main();
Improvements
Added min, max parameters to time generator
await seed(db, { timeTable: schema.timeTable }).refine((funcs) => ({
timeTable: {
count,
columns: {
time: funcs.time({
min: "13:12:13",
max: "15:12:13",
}),
},
},
}));
Added min, max parameters to timestamp generator
await seed(db, { timestampTable: schema.timestampTable }).refine((funcs) => ({
timestampTable: {
count,
columns: {
timestamp: funcs.timestamp({
min: "2025-03-07 13:12:13.123Z",
max: "2025-03-09 15:12:13.456Z",
}),
},
},
}));
Added min, max parameters to datetime generator
await seed(db, { datetimeTable: schema.datetimeTable }).refine((funcs) => ({
datetimeTable: {
count,
columns: {
datetime: funcs.datetime({
min: "2025-03-07 13:12:13Z",
max: "2025-03-09 15:12:13Z",
}),
},
},
}));
PostgreSQL sequences updating after seed
drizzle-seed iterates through each column in a table, selects columns of type smallint, integer, bigint, smallserial, serial, or bigserial, and (if a sequence exists) updates it to the column’s maximum seeded value.
select setval(pg_get_serial_sequence('"schema_name"."table_name"', 'column_name'), 3, true);
Breaking changes
uuid generator was changed and upgraded to v4
await seed(db, { table }).refine((f) => ({
table: {
columns: {
// AA97B177-9383-4934-8543-0F91A7A02836
// ^
// 1
// the digit at position 1 is always one of '8', '9', 'A' or 'B'
column1: f.uuid(),
}
}
}))
Reason for upgrade
UUID values generated by the old version of the uuid generator fail Zod’s v4 UUID validation.
example
import { createSelectSchema } from 'drizzle-zod';
import { seed } from 'drizzle-seed';
await seed(db, { uuidTest: schema.uuidTest }, { count: 1 }).refine((funcs) => ({
uuidTest: {
columns: {
col1: funcs.uuid()
}
}
})
);
const uuidSelectSchema = createSelectSchema(schema.uuidTest);
const res = await db.select().from(schema.uuidTest);
// the line below will throw an error when using old version of uuid generator
uuidSelectSchema.parse(res[0]);
Usage
await seed(db, schema);
// or explicit
await seed(db, schema, { version: '4' });
Switch to the old version
The previous version of uuid generator is v1.
await seed(db, schema, { version: '1' });
uuid generator:
await seed(db, schema, { version: '2' });
uuid generator:
await seed(db, schema, { version: '3' });
v1.0.0-beta.6 · v1.0.0-beta.6
2025-12-25 · by @AndriiSherman · prerelease
Bug fixes
- [BUG]: 1.0.0-beta.2 - drizzle-kit push does consider json (jsonb) key order relevant
- [BUG]: drizzle-kit pull generates string instead of sql statement for default value
- [BUG]: Failed schema with d1 table
- [BUG]: drizzle-kit: push runs already applied migration
- [BUG]: Drizzle-Kit detects change when Composite Primary Key Columns are in different order than in schema definition
- [BUG]: drizzle-kit push always shows columns with custom types as changed even tho the type didn't change;
1.0.0-beta.5 · v1.0.0-beta.5
2025-12-23 · by @AndriiSherman · prerelease
Bug fixes
- [BUG]: error: type "serial" does not exist
- [BUG]: jsonb default with boolean literals gets generated truen instead of true
- [BUG]: MSSQL view incorrect syntax
- Fixed
blobcolumns in MySQL to work properly with RQB mapper
Changes to SQLite drizzle-kit up command
Important!
If you were already using SQLite in any
beta.xversion and have used thedrizzle-kit upcommand, you will not receive the latestupchanges from this release. If you are unable to reset migrations and start from scratch, you will need to contact us for support with upgrading
What was changed?
Handling of UNIQUE constraints in SQLite
In the new version drizzle-kit handles UNIQUE constraints. This decision was made because when a unique constraint is created it cannot be removed, whereas an index can be dropped
Previous version of Drizzle-Kit always created .unique() as a uniqueIndex and stored it in the snapshot that way. Because of this during an up we lack of sufficient information and if a user used .unique() an upped will generate a diff on generate and push
Solution:
We are replacing all unique constraints with uniqueIndex
uniqueIndex requires a name and the name must follow this format:
<table>_<column1>*_*<column2>_..._unique
Foreign key name handling in the old(pre 1.0) drizzle-kit
The old drizzle-kit did not handle foreign key names when generated sql migrations. A foreign key name could be defined in the ts schema, but it was not passed through when generating sql
export const table = sqliteTable("table", {
column1: integer(),
column2: integer()},
(t) => [
foreignKey({
name: "name",
columns: [t.column1],
foreignColumns: [t.column2],
}),
]
);
// no name provided
FOREIGN KEY (`timest`) REFERENCES `b`(`timest1`) ON UPDATE no action ON DELETE no action
On introspect new drizzle-kit parses ddl to find constraint name, if no name found - use default name
After running drizzle-kit up the first push command will result in a diff that recreates the table (no name from db, but there is name in ts schema). To avoid this foreign key names should be removed - in that case no diff will be generated.
drizzle-kit generate command will behave as expected, no changes needed.
Bug in the old drizzle-kit related to foreign keys
If you add a column to an existing table that has a foreign key and specify onDelete or onUpdate, column will be added with the foreign key, but without those parameters
export const table = sqliteTable("table", {
column1: integer()
});
export const table = sqliteTable("table", {
column1: integer(),
column2: integer().references((): AnySQLiteColumn => table.column1,
{
onDelete: "set null",
onUpdate: "set default"
})
});
ALTER TABLE `table` ADD `column2` integer REFERENCES table(column1);
There is no way to fix this in the old snapshot. It led to table recreation during subsequent push operations (in the pre-v1.0 drizzle-kit version)
New drizzle-kit will recreate table after push command with the correct SQL. When using generate command, no diffs will appear, but the actual database state may differ
1.0.0-beta.4 · v1.0.0-beta.4
2025-12-23 · by @AndriiSherman · prerelease
Regression issues fixed(from -beta.x releases)
- [BUG]: migrations.sort in migrator.js does nothing - migrations run in wrong order on Linux
- [BUG]: drizzle-kit generate not working without error
Issues fixed(from latest tag)