Drizzle is a TypeScript ORM that generates SQL that looks like the SQL you would write by hand. No magic, no hidden queries, full type safety.
Why Drizzle Matters
Prisma generates opaque queries. TypeORM uses decorators and reflection. Drizzle gives you a thin, typed layer over SQL that you can read, understand, and optimize.
What you get for free:
- TypeScript-first with full type inference
- SQL-like syntax (select, where, join — looks like SQL)
- Zero overhead: generates exactly the SQL you expect
- PostgreSQL, MySQL, SQLite, Turso, Neon, PlanetScale
- Automatic migrations from schema changes
- Drizzle Studio: visual database browser
- Drizzle Kit: migration CLI
Quick Start
npm install drizzle-orm
npm install -D drizzle-kit
Schema Definition
import { pgTable, serial, text, timestamp, boolean, integer } from "drizzle-orm/pg-core";
export const users = pgTable("users", {
id: serial("id").primaryKey(),
name: text("name").notNull(),
email: text("email").notNull().unique(),
createdAt: timestamp("created_at").defaultNow(),
});
export const posts = pgTable("posts", {
id: serial("id").primaryKey(),
title: text("title").notNull(),
content: text("content"),
published: boolean("published").default(false),
authorId: integer("author_id").references(() => users.id),
createdAt: timestamp("created_at").defaultNow(),
});
Queries
import { db } from "./db";
import { users, posts } from "./schema";
import { eq, gt, desc, sql } from "drizzle-orm";
// Select
const allUsers = await db.select().from(users);
// Filter
const activeUsers = await db.select()
.from(users)
.where(eq(users.name, "Alice"));
// Join
const usersWithPosts = await db.select({
userName: users.name,
postTitle: posts.title,
})
.from(users)
.leftJoin(posts, eq(users.id, posts.authorId))
.where(eq(posts.published, true))
.orderBy(desc(posts.createdAt));
// Insert
const newUser = await db.insert(users).values({
name: "Alice",
email: "alice@example.com",
}).returning();
// Update
await db.update(users)
.set({ name: "Alice Updated" })
.where(eq(users.id, 1));
// Delete
await db.delete(users).where(eq(users.id, 1));
// Aggregation
const stats = await db.select({
authorId: posts.authorId,
postCount: sql<number>`count(*)`,
})
.from(posts)
.groupBy(posts.authorId)
.having(gt(sql`count(*)`, 5));
Migrations
# Generate migration from schema changes
npx drizzle-kit generate
# Apply migrations
npx drizzle-kit migrate
# Launch Drizzle Studio
npx drizzle-kit studio
Links
Building data-heavy TypeScript apps? Check out my developer tools on Apify or email spinov001@gmail.com for custom solutions.
Top comments (0)