Prisma vs Drizzle in Boilerplates
TL;DR
Drizzle wins in 2026 for new projects: smaller bundle, edge runtime support, SQL-like API, and faster queries. Prisma wins on DX and documentation: its schema language, type generation, and Prisma Studio are unmatched. Most new boilerplates are moving to Drizzle; most existing ones haven't migrated yet.
Side-by-Side Comparison
| Factor | Prisma | Drizzle |
|---|---|---|
| Bundle size | ~7MB | ~100KB |
| Edge runtime | ❌ (Prisma Client Engine) | ✅ |
| Query API | ORM-style | SQL-like |
| Type safety | Generated from schema | Inferred from code |
| Migrations | Prisma Migrate | Drizzle Kit |
| Studio/GUI | Prisma Studio ✅ | Drizzle Studio ✅ |
| Raw SQL | ✅ via $queryRaw | ✅ natural |
| Performance | Good | Excellent |
| Documentation | Excellent | Good |
| Community | Larger | Growing fast |
Query API Comparison
// Prisma — ORM-style (readable, but abstracts SQL)
const users = await prisma.user.findMany({
where: {
email: { endsWith: '@company.com' },
createdAt: { gte: new Date('2026-01-01') },
},
include: { subscription: true },
orderBy: { createdAt: 'desc' },
take: 20,
});
// Drizzle — SQL-like (verbose but explicit)
import { eq, gte, like, desc } from 'drizzle-orm';
const users = await db.select()
.from(usersTable)
.leftJoin(subscriptionsTable, eq(usersTable.id, subscriptionsTable.userId))
.where(
and(
like(usersTable.email, '%@company.com'),
gte(usersTable.createdAt, new Date('2026-01-01'))
)
)
.orderBy(desc(usersTable.createdAt))
.limit(20);
Schema Definition
// Prisma schema (separate .prisma file)
model User {
id String @id @default(cuid())
email String @unique
name String?
createdAt DateTime @default(now())
posts Post[]
subscription Subscription?
}
// Drizzle schema (TypeScript file)
import { pgTable, varchar, timestamp } from 'drizzle-orm/pg-core';
export const users = pgTable('users', {
id: varchar('id', { length: 128 }).primaryKey().$defaultFn(() => createId()),
email: varchar('email', { length: 255 }).notNull().unique(),
name: varchar('name', { length: 255 }),
createdAt: timestamp('created_at').notNull().defaultNow(),
});
// Types automatically inferred
type User = typeof users.$inferSelect;
type NewUser = typeof users.$inferInsert;
The Edge Runtime Decision
Prisma requires the Prisma Client Engine — a binary that runs alongside your Node.js process. This works on traditional servers but not on Cloudflare Workers, Deno Deploy, or Vercel Edge Functions.
Drizzle is pure JavaScript — it generates SQL and sends it to your database. Runs everywhere JavaScript runs.
If edge deployment is a requirement (Cloudflare Workers, Vercel Edge), Drizzle is the only option.
Which Boilerplates Use Which
| Boilerplate | ORM |
|---|---|
| ShipFast | Prisma (Mongoose option) |
| Supastarter | Prisma (with Supabase) |
| T3 Stack | Prisma (Drizzle option available) |
| Makerkit | Prisma |
| Epic Stack | Prisma |
| Bedrock | Drizzle (2025 update) |
| T3 Turbo | Drizzle variant growing |
Migration: Prisma → Drizzle
Migrating an existing Prisma project to Drizzle takes 1-3 days:
# 1. Generate Drizzle schema from existing DB
npx drizzle-kit introspect:pg
# 2. Replace prisma client calls with drizzle
# Before: const user = await prisma.user.findUnique({ where: { id } });
# After: const [user] = await db.select().from(users).where(eq(users.id, id));
# 3. Replace prisma migrations with drizzle-kit
npx drizzle-kit generate:pg
npx drizzle-kit push:pg
Find boilerplates using Prisma vs Drizzle on StarterPick.
Check out this boilerplate
View Drizzle ORM on StarterPick →