Drizzle
- Type-safe SQL queries (auto-completion)
- Lightweight & fast (no runtime overhead)
- Supports raw SQL when needed
- Schema migrations (via
drizzle-kit
) - Works with PostgreSQL, SQLite, MySQL, and more
Installation & Setup
npm install drizzle-orm
npm install drizzle-kit --save-dev # For migrations & CLI
Database Connection
import { drizzle } from 'drizzle-orm/node-postgres';
import { Pool } from 'pg';
const pool = new Pool({ connectionString: "postgres://user:pass@localhost:5432/db" });
const db = drizzle(pool);
import { drizzle } from 'drizzle-orm/better-sqlite3';
import Database from 'better-sqlite3';
const sqlite = new Database('sqlite.db');
const db = drizzle(sqlite);
Schema Definition
import { integer, pgTable, serial, text, varchar } from 'drizzle-orm/pg-core';
// Define a table
export const users = pgTable('users', {
id: serial('id').primaryKey(),
name: varchar('name', { length: 255 }),
email: varchar('email', { length: 255 }).unique(),
role: text('role', { enum: ['admin', 'user'] }).default('user'),
});
// Relations (1-to-many)
export const posts = pgTable('posts', {
id: serial('id').primaryKey(),
title: text('title'),
authorId: integer('author_id').references(() => users.id),
});
CRUD Operations
await db.insert(users).values({
name: 'Alice',
email: 'alice@example.com',
}).returning(); // Returns inserted record
// Get all users
const allUsers = await db.select().from(users);
// Get with WHERE condition
const user = await db.select().from(users).where(eq(users.email, 'alice@example.com'));
// Join tables
const postsWithAuthors = await db
.select({
postTitle: posts.title,
authorName: users.name,
})
.from(posts)
.leftJoin(users, eq(posts.authorId, users.id));
await db.update(users)
.set({ name: 'Bob' })
.where(eq(users.id, 1))
.returning(); // Returns updated records
await db.delete(users)
.where(eq(users.id, 1))
.returning(); // Returns deleted records
Migrations
drizzle.config.ts
import type { Config } from "drizzle-kit";
export default {
schema: "./src/schema.ts",
out: "./drizzle",
driver: "pg",
dbCredentials: { connectionString: "postgres://..." },
} satisfies Config;
npx drizzle-kit generate:pg # Generates SQL migration files
npx drizzle-kit push:pg # Applies migrations directly (dev)
Advanced Queries
Transactions
await db.transaction(async (tx) => {
await tx.insert(users).values({ name: 'Alice' });
await tx.insert(posts).values({ title: 'Hello', authorId: 1 });
});
Aggregations
const stats = await db
.select({
total: count(),
avgViews: avg(posts.views),
})
.from(posts);
Prepared Statements (SQL Injection-safe)
const getUser = db.query.users
.findFirst({ where: eq(users.id, sql.placeholder('id') })
.prepare();
const user = await getUser.execute({ id: 1 });