Drizzle Kit
Our most fundamental design principles of Drizzle ORM is to always stay explicit, provide opt-in solutions and never interfere. Our migrations toolkit is not an exception.
npm i -D drizzle-kit
yarn add -D drizzle-kit
pnpm add -D drizzle-kit
bun add -D drizzle-kit
Overview
Drizzle Kit β is a CLI companion for automatic SQL migrations generation and rapid prototyping.
Conceptually itβs very simple, you just declare a Drizzle ORM TypeScript schema and generate an SQL migration from it.
You can then change the original schema and Drizzle Kit will generate new migrations, that way you can have DDL source of truth in one type-safe place and under version control.
Drizzle Kit lets you split your schema in different files and even have multiple schemas for different databases in one project. You can rapidly prototype database schema and push it directly to the database.
Last but not least β you can pull the schema from an existing database in a matter of seconds β‘οΈ
Migration files
Migrations history is stored in .sql
files in the migrations folder
π¦ <project root>
β ...
β π drizzle
β β π _meta
β β π 0000_premium_mister_fear.sql
β β π 0001_absurd_toad.sql
β β π 0002_adorable_human_torch.sql
β β π 0003_boring_silver_sable.sql
β ...
β π src
β π package.json
β ...
Each SQL migration file contains statements which you apply to the database through. Drizzle ORM migration package or any other way suitable for your business case or personal preference.
CREATE TABLE IF NOT EXISTS "user" (
"id" serial,
"name" text,
"email" text,
"password" text,
"role" text,
"created_at" timestamp,
"updated_at" timestamp
);
export const user = pgTable("user", {
id: serial("id"),
name: text("name"),
email: text("email"),
password: text("password"),
role: text("role").$type<"admin" | "customer">(),
createdAt: timestamp("created_at"),
updatedAt: timestamp("updated_at"),
});
Schema updates
Whenever you apply changes to the schema you just rerun $ drizzle-kit generate...{:bash}
and
it will generate SQL migration for you completely automatically in most of the cases.
ALTER TABLE "user" ADD COLUMN "is_verified" boolean;
export const user = pgTable("user", {
id: serial("id"),
name: text("name"),
email: text("email"),
password: text("password"),
isVerified: boolean("is_verified"),
role: text("role").$type<"admin" | "customer">(),
createdAt: timestamp("created_at"),
updatedAt: timestamp("updated_at"),
});
Running migrations
Weβre unopinionated on how you should run your migrations, you can run them manually using SQL generated files, using external tools, etc. or use Drizzle ORM.
We provide you a useful way to run generated migrations with migrate
function which we implement for each driver and dialect specifically.
Drizzle will automatically keep track of applied migrations in your database.
drizzle
and migrate
imports depend on the database driver youβre using.
import { drizzle } from "drizzle-orm/postgres-js";
import { migrate } from "drizzle-orm/postgres-js/migrator";
import postgres from "postgres";
const sql = postgres("...", { max: 1 })
const db = drizzle(sql);
await migrate(db, { migrationsFolder: "drizzle" });
import { drizzle } from "drizzle-orm/mysql2";
import { migrate } from "drizzle-orm/mysql2/migrator";
import { createConnection } from "mysql2";
const connection = createConnection("...")
const db = drizzle(connection);
await migrate(db, { migrationsFolder: "drizzle" });
import { drizzle } from "drizzle-orm/better-sqlite3";
import { migrate } from "drizzle-orm/better-sqlite3/migrator";
import Database from "better-sqlite3";
const betterSqlite = new Database(":memory:");
const db = drizzle(betterSqlite);
migrate(db, { migrationsFolder: "drizzle" });
Configuration
Drizzle Kit lets you declare configurations in TypeScript
, JavaScript
or JSON
configuration files.
You can have autocomplete experience and a very convenient environment variables flow!
import { defineConfig } from 'drizzle-kit/utils'
export default defineConfig({
schema: "./schema.ts",
driver: 'pg',
dbCredentials: {
connectionString: process.env.DB_URL,
},
verbose: true,
strict: true,
})
/** @type { import("drizzle-kit").Config } */
export default {
schema: "./schema.ts",
driver: 'pg',
dbCredentials: {
connectionString: process.env.DB_URL,
}
};
{
"out": "./migrations-folder",
"schema": "./src/db",
"breakpoints": false
}
For list of all configuration params β see here.
Prototyping with db push
Drizzle Kit lets you alter you database schema and rapidly move forward with a db push
command.
Thatβs very handy when you have remote databases like Neon, Planetscale or Turso.
Overview
If you want to iterate quickly during local development or if your project doesnβt require
migration files, Drizzle offers a useful command called drizzle-kit push
.
When do you need to use the βpushβ command?
- During the prototyping and experimentation phase of your schema on a local environment.
- When you are utilizing an external provider that manages migrations and schema changes for you (e.g., PlanetScale).
- If you are comfortable modifying the database schema before your code changes can be deployed.
How it works?
When you run the command drizzle-kit push
drizzle executes the following steps:
- It retrieves your schema from the database and converts it to the βdrizzle-schemaβ format.
- The command reads all your schema files containing drizzle tables and converts them to the βdrizzle-schemaβ format as well.
- Drizzle then compares the two schemas and generates a set of statements that need to be executed against your database. These statements ensure that the database is synchronized with the schemas defined in your code.
$ drizzle-kit push:mysql
$ drizzle-kit push:sqlite
For extended push
examples see here.
Introspecting with db pull
Drizzle Kit lets you pull DDL from existing database and prints a TypeScript schema file completely automatically.
$ drizzle-kit introspect:mysql ...
π¦ <project root>
β ...
β π drizzle
β β π _meta
β β π 0000_premium_mister_fear.sql
β β π schema.ts
β ...
β π src
β π package.json
β ...
export const user = pgTable("user", {
id: serial("id"),
name: text("name"),
email: text("email"),
password: text("password"),
role: text("role").$type<"admin" | "customer">(),
createdAt: timestamp("created_at"),
updatedAt: timestamp("updated_at"),
});
For extended introspect
examples β see here.
Drizzle Studio [NEW]
Drizzle Kit comes with bundled Drizzle Studio database browser and lets you launch it locally with one command.
Studio requires drizzle config file with schema
and dbCredentials
provided.
drizzle-kit studio
drizzle-kit studio --port 3000 ## custom port
drizzle-kit studio --verbose ## log all sql statements