Public Wiki32,699View on GitHub
Want drizzle-team/drizzle-orm knowledge in your AI?

Drizzle ORM

Drizzle is a TypeScript ORM and database toolkit consisting of two main packages: drizzle-orm (a type-safe ORM supporting PostgreSQL, MySQL, SQLite, SingleStore, and Gel/EdgeDB) and drizzle-kit (a CLI for schema migrations, introspection, and Drizzle Studio). It also includes schema validation packages (drizzle-zod, drizzle-valibot, drizzle-typebox, drizzle-arktype) and a database seeding tool (drizzle-seed).

Tech Stack

Drizzle ORMPostgreSQLZodPrismaTypeScriptRedisReactVitest

Key Features

  • Multi-dialect SQL query builder
  • SQL template tag and expression system
  • Relational query API
  • 15+ driver adapters
  • Schema migration engine
  • Database introspection (pull)
  • Database push
  • Drizzle Studio API
  • Schema validation integrations
  • Database seeding
  • Query caching
  • CLI with terminal UI
  • ESLint plugin
  • Knex and Kysely type integrations

Entry Points

Start here when working with this codebase

ORM Core Entry
drizzle-orm/src/index.ts

Main export barrel for all drizzle-orm public APIs including SQL primitives, column types, relations, and driver adapters

Start here when adding new core ORM features, understanding what's publicly exported, or tracing how users import drizzle-orm

PostgreSQL Dialect Entry
drizzle-orm/src/pg-core/index.ts

Exports all PostgreSQL-specific column types, query builders, table definitions, policies, roles, and views

Start here when adding new PostgreSQL column types, query builder methods, or PG-specific features

MySQL Dialect Entry
drizzle-orm/src/mysql-core/index.ts

Exports all MySQL-specific column types, query builders, table definitions, and views

Start here when adding new MySQL column types, query builder methods, or MySQL-specific features

SQLite Dialect Entry
drizzle-orm/src/sqlite-core/index.ts

Exports all SQLite-specific column types, query builders, table definitions, and views

Start here when adding new SQLite column types, query builder methods, or SQLite-specific features

SingleStore Dialect Entry
drizzle-orm/src/singlestore-core/index.ts

Exports all SingleStore-specific column types, query builders, and schema definitions

Start here when adding SingleStore-specific features or column types

Gel Dialect Entry
drizzle-orm/src/gel-core/index.ts

Exports Gel (EdgeDB) dialect columns, query builders, policies, and views

Start here when working on Gel/EdgeDB dialect features

SQL Builder Entry
drizzle-orm/src/sql/index.ts

Core SQL template tag, expressions, conditions, aggregate functions, and SQL primitives used by all dialects

Start here when modifying SQL generation, adding new SQL expressions, or changing how queries are built

Kit CLI Entry
drizzle-kit/src/cli/index.ts

CLI command definitions and argument parsing for drizzle-kit commands (generate, migrate, push, pull, studio)

Start here when adding new CLI commands or modifying existing command behavior

Kit Serializer Entry
drizzle-kit/src/serializer/index.ts

Schema serialization/deserialization orchestration for converting Drizzle schemas to JSON snapshots

Start here when modifying how schemas are serialized for migration generation

Kit API Entry
drizzle-kit/src/api.ts

Programmatic API for drizzle-kit operations (generate, push, pull) without CLI

Start here when adding programmatic access to kit features or understanding the public kit API

Studio Endpoint
drizzle-kit/src/serializer/studio.ts

Unified POST endpoint handling all Drizzle Studio operations through type-discriminated requests

Start here when modifying Studio server behavior or adding new Studio operations

ORM Build Config
drizzle-orm/tsup.config.ts

tsup build configuration defining all entry points, output formats, and external dependencies for drizzle-orm

Start here when adding new subpath exports to drizzle-orm or changing build output

Kit Build Config
drizzle-kit/build.ts

esbuild configuration for compiling and bundling drizzle-kit into distributable artifacts

Start here when modifying drizzle-kit build process or adding new bundled modules

Cache Layer Entry
drizzle-orm/src/cache/index.ts

Query caching abstraction with core cache interface and Upstash implementation

Start here when adding new cache providers or modifying caching behavior

How to Make Changes

Common modification patterns for this codebase

Add a new PostgreSQL column type

1
drizzle-orm/src/pg-core/columns

Create a new column file (e.g., mytype.ts) defining the column builder and column classes

Pattern: Follow the pattern in drizzle-orm/src/pg-core/columns/integer.ts: export a builder class extending PgColumnBuilder, a column class extending PgColumn, and a factory function. The builder must implement build() returning the column instance, and the column must implement getSQLType() returning the SQL type string and mapFromDriverValue()/mapToDriverValue() if needed

2
drizzle-orm/src/pg-core/columns/index.ts

Re-export the new column type from the columns barrel file

Pattern: Add an export line matching the existing pattern: export * from './mytype.ts' following the alphabetical ordering used in drizzle-orm/src/pg-core/columns/index.ts

3
drizzle-orm/src/pg-core/index.ts

Verify the new column is transitively exported through the columns barrel

Pattern: The pg-core index.ts re-exports from './columns/index.ts' so no change needed if step 2 is done correctly

4
drizzle-kit/src/serializer/pgSerializer.ts

Add serialization support for the new column type so drizzle-kit can snapshot it

Pattern: Follow how existing column types are handled in the column serialization switch/if-else chain in pgSerializer.ts. Map the column class to its SQL type name and any type-specific parameters

5
drizzle-kit/src/serializer/pgSchema.ts

If the column type has special parameters, add them to the Zod schema for PG column snapshots

Pattern: Follow how enumerated types or array types add extra fields in the column schema definition in pgSchema.ts

6
drizzle-kit/src/introspect-pg.ts

Add introspection support so 'drizzle-kit pull' can generate code for this column type from an existing database

Pattern: Follow how existing types are mapped from database introspection results to Drizzle column builder calls in introspect-pg.ts

7
integration-tests/tests/pg

Add integration tests covering insert, select, update, and filtering with the new column type

Pattern: Follow the test structure in existing PG integration test files under integration-tests/tests/pg/ that define a table with the column, insert values, and assert round-trip correctness

Conventions to follow:

Column builder classes are named like PgMyTypeBuilder and extend PgColumnBuilderColumn classes are named like PgMyType and extend PgColumnThe public factory function is a plain function (e.g., export function mytype()) that returns a PgMyTypeBuilder instanceUse branded types via ColumnBuilderBaseConfig and ColumnBaseConfig genericsgetSQLType() must return the exact PostgreSQL type name stringIf the JS type differs from the driver's return type, implement mapFromDriverValue() and mapToDriverValue()

Add a new MySQL column type

1
drizzle-orm/src/mysql-core/columns

Create a new column file defining builder and column classes

Pattern: Follow the pattern in drizzle-orm/src/mysql-core/columns/int.ts: export a builder class extending MySqlColumnBuilder, a column class extending MySqlColumn, and a factory function

2
drizzle-orm/src/mysql-core/columns/index.ts

Re-export the new column type from the columns barrel file

Pattern: Add export * from './mytype.ts' matching the existing exports in drizzle-orm/src/mysql-core/columns/index.ts

3
drizzle-kit/src/serializer/mysqlSerializer.ts

Add serialization support for the new column type

Pattern: Follow how existing MySQL column types are serialized in mysqlSerializer.ts

4
drizzle-kit/src/serializer/mysqlSchema.ts

Add any type-specific parameters to the MySQL column Zod schema if needed

Pattern: Follow existing column parameter definitions in mysqlSchema.ts

5
drizzle-kit/src/introspect-mysql.ts

Add introspection mapping for the new column type

Pattern: Follow how existing MySQL types are mapped in introspect-mysql.ts

Conventions to follow:

MySQL column builders extend MySqlColumnBuilder, columns extend MySqlColumnFactory functions follow the same naming pattern as drizzle-orm/src/mysql-core/columns/int.tsgetSQLType() returns the exact MySQL type string

Add a new SQLite column type

1
drizzle-orm/src/sqlite-core/columns

Create a new column file defining builder and column classes

Pattern: Follow the pattern in drizzle-orm/src/sqlite-core/columns/integer.ts: export a builder class extending SQLiteColumnBuilder, a column class extending SQLiteColumn, and a factory function

2
drizzle-orm/src/sqlite-core/columns/index.ts

Re-export the new column type

Pattern: Add export * from './mytype.ts' matching existing exports in drizzle-orm/src/sqlite-core/columns/index.ts

3
drizzle-kit/src/serializer/sqliteSerializer.ts

Add serialization support for the new column type

Pattern: Follow how existing SQLite column types are serialized in sqliteSerializer.ts

4
drizzle-kit/src/introspect-sqlite.ts

Add introspection mapping for the new column type

Pattern: Follow how existing SQLite types are mapped in introspect-sqlite.ts

Conventions to follow:

SQLite column builders extend SQLiteColumnBuilder, columns extend SQLiteColumnSQLite has limited type affinity (TEXT, INTEGER, REAL, BLOB) so getSQLType() should return the appropriate affinity

Add a new database driver adapter

1
drizzle-orm/src

Create a new directory for the driver (e.g., drizzle-orm/src/my-driver/) with session.ts, driver.ts, and index.ts files

Pattern: Follow the structure of drizzle-orm/src/node-postgres/ which has session.ts (NodePgSession extending PgSession), driver.ts (NodePgDriver and drizzle() factory), and index.ts (barrel exports)

2
drizzle-orm/src/my-driver/session.ts

Create a session class that extends the dialect's base session and implements execute(), all(), and transaction methods

Pattern: Follow drizzle-orm/src/node-postgres/session.ts: NodePgSession extends PgSession, implements execute() that calls the underlying driver client, wraps results in proper format, and handles prepared statements

3
drizzle-orm/src/my-driver/driver.ts

Create a driver class and the public drizzle() factory function that users call to create a database instance

Pattern: Follow drizzle-orm/src/node-postgres/driver.ts: export a drizzle() function that accepts the driver client and optional config, creates a session, and returns a PgDatabase (or MySqlDatabase/BaseSQLiteDatabase) instance

4
drizzle-orm/src/my-driver/index.ts

Create barrel exports for the driver module

Pattern: Follow drizzle-orm/src/node-postgres/index.ts: re-export session, driver, and the drizzle factory function

5
drizzle-orm/tsup.config.ts

Add the new driver as an entry point in the tsup build configuration

Pattern: Add 'src/my-driver/index.ts' to the entry array in drizzle-orm/tsup.config.ts, following how 'src/node-postgres/index.ts' and other drivers are listed

6
drizzle-orm/package.json

Add subpath exports for the new driver module and add the underlying driver package as an optional peerDependency

Pattern: Follow how './node-postgres' is defined in the exports map and peerDependencies/peerDependenciesMeta in drizzle-orm/package.json

Conventions to follow:

Session classes extend the dialect's base session (PgSession, MySqlSession, SQLiteSession)The drizzle() factory function is the primary public API for creating a database instanceDriver packages are optional peerDependencies with peerDependenciesMeta marking them as optionalEach driver gets its own subpath export in package.json (e.g., 'drizzle-orm/my-driver')Use the ~ import alias for internal drizzle-orm imports within the driver code

Add a new query builder method (e.g., new clause like RETURNING, ON CONFLICT)

1
drizzle-orm/src/pg-core/query-builders

Add the new method to the appropriate query builder class (select.ts, insert.ts, update.ts, or delete.ts)

Pattern: Follow how .where() is implemented in drizzle-orm/src/pg-core/query-builders/select.ts: add a method that stores the clause data in the builder's config object and returns 'this' for chaining. The method should accept SQL expressions from drizzle-orm/src/sql/index.ts

2
drizzle-orm/src/pg-core/dialect.ts

Modify the dialect's SQL generation method to include the new clause in the final SQL output

Pattern: Follow how PgDialect.buildSelectQuery() in drizzle-orm/src/pg-core/dialect.ts reads config properties and appends SQL chunks. Add your clause generation in the correct position within the SQL statement

3
drizzle-orm/src/mysql-core/query-builders

If the clause applies to MySQL, add the equivalent method to MySQL query builders

Pattern: Follow the same pattern as step 1 but in drizzle-orm/src/mysql-core/query-builders/

4
drizzle-orm/src/mysql-core/dialect.ts

If applicable, modify MySQL dialect SQL generation

Pattern: Follow drizzle-orm/src/mysql-core/dialect.ts buildSelectQuery() or equivalent method

5
drizzle-orm/src/sqlite-core/query-builders

If the clause applies to SQLite, add the equivalent method to SQLite query builders

Pattern: Follow the same pattern in drizzle-orm/src/sqlite-core/query-builders/

6
drizzle-orm/src/sqlite-core/dialect.ts

If applicable, modify SQLite dialect SQL generation

Pattern: Follow drizzle-orm/src/sqlite-core/dialect.ts buildSelectQuery() or equivalent method

Conventions to follow:

Query builder methods return 'this' for method chainingSQL generation happens in the dialect class, not in the query builderQuery builders store configuration; dialects read configuration and produce SQLUse the sql template tag from drizzle-orm/src/sql/index.ts for building SQL fragmentsType-level changes should preserve the builder's generic type parameters for type inference

Add a new SQL function or expression

1
drizzle-orm/src/sql/expressions/index.ts

Add the new SQL function as an exported function that returns a SQL expression

Pattern: Follow how existing functions like eq(), and(), or(), sql.raw() are defined in drizzle-orm/src/sql/expressions/index.ts. Return a new SQL instance using the sql template tag or SQL constructor from drizzle-orm/src/sql/sql.ts

2
drizzle-orm/src/sql/index.ts

Re-export the new function from the SQL barrel file if not already covered by the expressions re-export

Pattern: Check drizzle-orm/src/sql/index.ts to see how expressions are re-exported

3
drizzle-orm/src/index.ts

Ensure the new function is exported from the main drizzle-orm entry point

Pattern: Check that drizzle-orm/src/index.ts re-exports from './sql/index.ts' which should transitively include the new function

Conventions to follow:

SQL functions return SQL<T> instances where T is the return typeUse the sql template tag for constructing SQL: sql`FUNCTION_NAME(${arg})`Comparison operators (eq, gt, etc.) are in drizzle-orm/src/sql/expressions/conditions.tsFunctions should accept Column | SQL | Placeholder types as arguments for flexibility

Coding Conventions

Standards and patterns used in this codebase

Build Configuration

Validation/integration packages use Rollup with consistent plugin chain (typescript2, resolve, terser) outputting both ESM (.mjs) and CJS (.cjs) formats, while the core ORM uses tsup for building.

export default defineConfig([{ input: 'src/index.ts', output: [{ format: 'esm', file: 'dist/index.mjs' }, { format: 'cjs', file: 'dist/index.cjs' }], plugins: [typescript2(), resolve(), terser()] }])
drizzle-arktype/rollup.config.tsdrizzle-zod/rollup.config.tsdrizzle-typebox/rollup.config.tsdrizzle-valibot/rollup.config.ts
Testing

All packages use Vitest as the test runner with a consistent vitest.config.ts pattern using defineConfig. Test timeouts are set generously (typically 100000ms) for database integration tests.

import { defineConfig } from 'vitest/config'; export default defineConfig({ test: { include: ['tests/**/*.test.ts'], testTimeout: 100000 } });
drizzle-seed/vitest.config.tsdrizzle-zod/vitest.config.tsdrizzle-typebox/vitest.config.tseslint-plugin-drizzle/vitest.config.ts
Build Configuration

External dependencies (including the parent drizzle-orm package and validation libraries) are explicitly listed in the Rollup external array to prevent bundling peer dependencies.

external: ['drizzle-orm', 'drizzle-orm/pg-core', 'drizzle-orm/mysql-core', 'drizzle-orm/sqlite-core', 'drizzle-orm/singlestore-core', 'drizzle-orm/gel-core', 'drizzle-orm/column', 'zod']
drizzle-zod/rollup.config.tsdrizzle-valibot/rollup.config.tsdrizzle-arktype/rollup.config.ts
Build Configuration

Rollup configs consistently use @rollup/plugin-typescript2 (not the standard @rollup/plugin-typescript) with tsconfig set to 'tsconfig.build.json', separating build config from development config.

typescript2({ tsconfig: 'tsconfig.build.json' })
drizzle-zod/rollup.config.tsdrizzle-seed/rollup.config.tsdrizzle-typebox/rollup.config.ts
Testing

Test files follow the naming pattern *.test.ts and are located in a top-level 'tests/' directory. Vitest configs use glob patterns like 'tests/**/*.test.ts' for test discovery.

test: { include: ['tests/**/*.test.ts'] }
drizzle-zod/vitest.config.tsdrizzle-valibot/vitest.config.tseslint-plugin-drizzle/vitest.config.ts
Build Configuration

The drizzle-seed package supports multiple entry points in its Rollup config to handle different database dialect exports, each producing separate ESM and CJS output files.

defineConfig([{ input: 'src/index.ts', output: [{ format: 'esm', file: 'dist/index.mjs' }, { format: 'cjs', file: 'dist/index.cjs' }] }])
drizzle-seed/rollup.config.ts
Project Structure

The monorepo follows a flat package structure where each package (drizzle-orm, drizzle-kit, drizzle-zod, drizzle-valibot, drizzle-typebox, drizzle-arktype, drizzle-seed, eslint-plugin-drizzle) is a top-level directory with its own build and test configuration.

drizzle-orm/, drizzle-kit/, drizzle-zod/, drizzle-valibot/, drizzle-typebox/, drizzle-arktype/, drizzle-seed/
drizzle-zod/rollup.config.tsdrizzle-orm/tsup.config.tsdrizzle-seed/rollup.config.ts
Build Configuration

TypeScript configuration is split into separate tsconfig files: a base tsconfig.json for development/IDE and a tsconfig.build.json for production builds with stricter or different settings.

typescript2({ tsconfig: 'tsconfig.build.json' })
drizzle-zod/rollup.config.tsdrizzle-arktype/rollup.config.tsdrizzle-valibot/rollup.config.ts