Why Drizzle ORM?
When your app talks to a database, it uses a language called SQL — structured queries like SELECT * FROM users WHERE id = 1. SQL works, but writing it by hand inside your JavaScript code is awkward. You lose autocomplete, you get no type checking, and a typo in a column name only shows up when your app crashes.
An ORM (Object-Relational Mapper) sits between your code and the database. Instead of writing raw SQL strings, you write JavaScript — and the ORM translates it into SQL for you.
?Why SQLite?What Drizzle gives you
Drizzle is a TypeScript-first ORM. That means your editor knows your database structure and can help you write correct queries:
// Instead of: "SELECT * FROM forms WHERE id = ?"
const form = await db.query.forms.findFirst({
where: eq(forms.id, formId),
})
If you rename a column in your schema, every query that references it lights up with an error — before your app ever runs. That's the kind of safety net that saves hours of debugging.
Schema as code
With Drizzle, your database structure is defined in regular TypeScript files. A table looks like this:
export const forms = sqliteTable('forms', {
id: integer().primaryKey({ autoIncrement: true }),
title: text().notNull(),
})
This file is your source of truth. When you change it, Drizzle generates a migration — a small SQL script that updates your database to match. No manual SQL writing, no guessing what changed.
Why not Prisma?
Prisma is popular and productive. For many apps, it works great.
But there are trade-offs:
- Client generation. Prisma uses a separate
.prismaschema and requires runningprisma generateto produce a typed client. Forget that step — locally, in CI, after a schema change — and you get stale types or broken builds. It's a small thing that bites you often. - Heavy runtime. Prisma historically shipped a Rust-based query engine binary. Prisma 7 moved query execution to TypeScript, but the toolchain (schema parsing,
prisma generate) still relies on Rust/WASM under the hood — and you still need the codegen step either way. - Unpredictable queries. A single Prisma call can silently fire multiple SQL statements — especially with nested
includeand relations. You don't see it until something is slow. With Drizzle, one call = one SQL query. What you write is what runs.
Drizzle keeps everything in TypeScript. Your schema is your types — no generation step, no sync issues. No extra engine. Queries stay close to how SQL actually works.
If you care about predictability, smaller deploy surface, and fewer moving parts — Drizzle stays closer to the metal.
AI writes it well
Drizzle schemas and queries are plain TypeScript. No custom DSL. No generated client drift. AI tools read the schema and write consistent queries — just like any other TypeScript code.