Prisma abstracts SQL away. Drizzle embraces it. If you already know SQL and want full type safety without learning a new query language, Drizzle ORM is the fastest-growing alternative in the TypeScript ecosystem.
What Drizzle Gives You for Free
- SQL-like query syntax — if you know SQL, you know Drizzle
- Full type safety — schema-driven types, no code generation step
- Zero dependencies — ~7KB bundle, no native binaries
- Drizzle Kit — migrations, introspection, studio
- Supports PostgreSQL, MySQL, SQLite — with serverless drivers (Neon, Turso, PlanetScale)
- Works everywhere — Node, Bun, Deno, Cloudflare Workers, edge runtimes
Quick Start
npm install drizzle-orm postgres
npm install -D drizzle-kit
Schema Definition (TypeScript, Not a DSL)
// src/db/schema.ts
import { pgTable, serial, text, boolean, timestamp, integer } from 'drizzle-orm/pg-core';
export const users = pgTable('users', {
id: serial('id').primaryKey(),
email: text('email').unique().notNull(),
name: text('name'),
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)
});
Your schema IS your types. No generation step needed.
Queries That Look Like SQL
import { db } from './db';
import { users, posts } from './db/schema';
import { eq, and, like, desc } from 'drizzle-orm';
// SELECT * FROM users WHERE email = ?
const user = await db.select().from(users)
.where(eq(users.email, 'alex@dev.to'));
// JOIN query — reads like SQL
const userPosts = await db
.select({
userName: users.name,
postTitle: posts.title,
published: posts.published
})
.from(users)
.leftJoin(posts, eq(users.id, posts.authorId))
.where(and(
like(users.email, '%gmail.com'),
eq(posts.published, true)
))
.orderBy(desc(posts.id))
.limit(10);
If you can write SQL, you can write Drizzle. Every query maps 1:1 to the SQL it generates.
Relational Queries (When You Want Prisma-Style)
// Drizzle also has a Prisma-like relational API:
const result = await db.query.users.findMany({
with: {
posts: {
where: eq(posts.published, true),
limit: 5
}
}
});
Best of both worlds — SQL-like for complex queries, relational for simple ones.
Migrations
# Generate migration from schema changes
npx drizzle-kit generate
# Apply migrations
npx drizzle-kit migrate
# Push schema directly (development)
npx drizzle-kit push
# Open Drizzle Studio (visual DB browser)
npx drizzle-kit studio
Edge-Ready: Serverless Drivers
// Neon (serverless PostgreSQL)
import { neon } from '@neondatabase/serverless';
import { drizzle } from 'drizzle-orm/neon-http';
const sql = neon(process.env.DATABASE_URL!);
const db = drizzle(sql);
// Turso (SQLite at the edge)
import { createClient } from '@libsql/client';
import { drizzle } from 'drizzle-orm/libsql';
const client = createClient({ url: 'libsql://...' });
const db = drizzle(client);
Drizzle's zero-dependency design means it works in Cloudflare Workers, Vercel Edge, and any serverless environment.
Drizzle vs Prisma
| Aspect | Drizzle | Prisma |
|---|---|---|
| Query style | SQL-like | Custom DSL |
| Type generation | From schema (instant) | From prisma generate
|
| Bundle size | ~7KB | ~2MB (with engine) |
| Edge support | Native | Requires Accelerate |
| Raw SQL | Built-in sql template |
$queryRaw |
| Learning curve | Know SQL → know Drizzle | Learn Prisma's API |
| Maturity | Newer, fast-growing | Battle-tested |
The Verdict
Drizzle is for developers who think in SQL and want TypeScript to verify their queries. Zero overhead, edge-ready, and growing fast. If Prisma feels like too much abstraction, Drizzle is your answer.
Need help building production web scrapers or data pipelines? I build custom solutions for startups and enterprises. Reach out: spinov001@gmail.com
Check out my awesome-web-scraping collection — 400+ tools for extracting web data.
Top comments (0)