Drizzle ORM

rising

A lightweight, type-safe TypeScript ORM that feels like writing SQL. Zero runtime overhead, excellent migration tooling, and first-class serverless support.

AI9/10Production8/10easy setuplow learning curveReviewed Mar 2026

Quick Verdict

Drizzle is the ORM that TypeScript developers who know SQL actually enjoy using. It maps 1:1 to SQL — if you can write a JOIN, you know Drizzle. Zero runtime overhead, excellent type inference, and the best serverless database story in the ecosystem.

When to use it: You're on serverless, you know SQL, and you want AI tools to generate accurate database queries.

When not to: Your team prefers high-level abstractions and doesn't want to think in SQL.

Best For

  • Serverless deployments — no binary, no engine to boot, ~50ms cold start vs Prisma's 300–500ms
  • AI-assisted development — the SQL-like API maps to what LLMs know, fewer hallucinations
  • Teams that know SQL — Drizzle doesn't abstract it away, it types it
  • Next.js + Neon — the native serverless driver was built for this combination

Avoid If

  • Your team prefers a higher-level ORM abstraction (Prisma's findMany + include is more ergonomic for non-SQL thinkers)
  • You need the Prisma ecosystem (Accelerate, Pulse, Studio, many third-party adapters)
  • Non-TypeScript project — Drizzle doesn't exist outside TypeScript

Why People Choose It

Prisma dominated the TypeScript ORM space, but developers grew frustrated with the Rust-based query engine, the generated client, and cold-start overhead in serverless. Drizzle emerged as the "type safety on top of SQL I already understand" alternative.

The serverless story sealed the deal. Drizzle's zero-overhead design means no binary dependencies and native support for HTTP-based database drivers (Neon serverless, PlanetScale serverless). In a Vercel function, that's 50ms vs 500ms cold starts.

Hidden Costs

Essentially zero direct cost — Drizzle and drizzle-kit are free. The real cost is migration tooling maturity. drizzle-kit is younger than prisma migrate and has had edge cases with complex schema changes. Always test migrations in a branch before applying to production.

Correct vs Cargo-Culted Patterns

Wrong — using the relational API for complex queries:

prompt
// ❌ The relational API is convenient but inflexible
const result = await db.query.users.findMany({
  with: { posts: { where: { published: true } } },
})

Right — SQL-like builder for complex cases:

prompt
// ✅ Explicit, readable, performant
const result = await db
  .select({ user: users, post: posts })
  .from(users)
  .leftJoin(posts, and(eq(posts.userId, users.id), eq(posts.published, true)))
  .where(eq(users.active, true))

Wrong — forgetting atomicity:

prompt
// ❌ Two separate awaits — no transaction
await db.insert(orders).values({ ... })
await db.update(inventory).set({ ... })

Right — transaction wrapper:

prompt
// ✅ Atomic — both succeed or both fail
await db.transaction(async (tx) => {
  await tx.insert(orders).values({ ... })
  await tx.update(inventory).set({ ... })
})

AI Coding Notes

Drizzle produces the most accurate AI-generated database code of any TypeScript ORM. The SQL-like API closely matches what LLMs know about SQL. Always provide your schema.ts file as context — this dramatically improves query generation accuracy.

Common AI Mistakes

  1. Wrong driver importdrizzle-orm/postgres-js vs drizzle-orm/neon-serverless — different packages, different connection patterns. Match to your database provider.
  2. Missing transactions — AI generates multi-table writes as sequential awaits, not wrapped in db.transaction(). Atomicity bugs surface under concurrent load.
  3. Relational API for complex queries — elegant for simple cases, inflexible for complex joins. Use the SQL-like builder.
  4. Not running drizzle-kit — Drizzle does not auto-migrate. Always run drizzle-kit generate + drizzle-kit push after schema changes.
  5. Ignoring $inferInsert / $inferSelect — these give you insert/select types from the schema. Use them instead of manually defining interfaces.

Start With / Grow Into / Avoid Until Needed

Start with Drizzle if you're on serverless and your team knows SQL. The learning curve is minimal for SQL-fluent developers.

Grow into the relational API (db.query.*) for simple CRUD once you're comfortable — it's more ergonomic for basic operations.

Avoid until needed: Raw SQL escapes (db.execute(sql\...`)`). Use only when the query builder genuinely can't express what you need.

Migration Implications

Moving from Drizzle to Prisma (or vice versa) is 2–5 days of query rewrites for a mid-size app:

  • Convert schema definitions
  • Rewrite all queries to the new API
  • Re-establish migration history

The database itself (Postgres) is portable — it's the query layer that requires work.

Alternatives

  • Prisma — richer abstraction, larger ecosystem, better GUI tooling. Heavier runtime, slower in serverless. See Drizzle vs Prisma.