TypeScript developers increasingly reach for query builders instead of full ORMs — they want type safety without the magic. Drizzle ORM, Kysely, and Knex.js represent three approaches to this problem: Drizzle is a lightweight ORM with a query-builder feel, Kysely is a pure type-safe query builder, and Knex.js is the veteran that predates TypeScript. This comparison helps you pick the right level of abstraction.
Quick Comparison
| Feature | Drizzle ORM | Kysely | Knex.js |
|---|---|---|---|
| Type | Lightweight ORM + query builder | Type-safe SQL query builder | SQL query builder (JS first) |
| Language | TypeScript | TypeScript | JavaScript (+ @types/knex for TS) |
| Type Safety | Excellent — inferred from schema | Excellent — inferred from Database interface | Moderate — TS types are add-on, not core |
| Schema Definition | Code-first (TypeScript schemas + drizzle-kit) | Manual (define Database type interface) | Migrations (knex migrate:make) |
| Migration Tool | drizzle-kit (SQL + TypeScript migrations) | None built-in (use kysely-codegen + manual) | Built-in (knex migrate:make/latest/rollback) |
| Supported Databases | PostgreSQL, MySQL, SQLite, Turso, Neon, Planetscale, Xata, SingleStore | PostgreSQL, MySQL, SQLite, MSSQL (via dialects) | PostgreSQL, MySQL, SQLite, MSSQL, Oracle, Redshift, CockroachDB |
| Relationship Queries | relations() API, findMany with joins | Manual JOINs (no relation abstraction) | Manual JOINs |
| Raw SQL Escape Hatch | sql tagged template | sql tagged template | knex.raw() |
| Connection Pooling | Via drivers (pg, mysql2, better-sqlite3) | Via drivers (pg, mysql2, better-sqlite3) | Built-in (tarn.js) |
| Bundle Size | ~10 KB (core) | ~15 KB | ~40 KB |
When Each Tool Wins
Drizzle ORM — Best for: Teams that want a happy medium between a full ORM (Prisma) and raw SQL. Drizzle's schema-in-TypeScript approach gives you end-to-end type safety without code generation. The relations API handles basic joins while giving you raw SQL escape hatches when needed. Weak spot: Newer than Knex.js; smaller community; less documentation for complex patterns.
Kysely — Best for: Developers who want maximum control with full type safety. Kysely is strictly a query builder — no schema management, no migrations, no relation abstractions. You define a TypeScript interface for your database schema, and Kysely infers types from that. Weak spot: More boilerplate — you manually define the Database type interface; no built-in migrations (use kysely-codegen or manage separately); steeper learning curve.
Knex.js — Best for: Teams with existing Knex.js codebases, teams that need broad database support (Oracle, Redshift), and teams that are not using TypeScript or are early in their TS migration. Weak spot: TypeScript support is bolted on, not built in; the query builder API is less ergonomic than Drizzle or Kysely for complex queries.
Decision Matrix
| Situation | Best Tool | Why |
|---|---|---|
| New TypeScript project, want ORM-lite | Drizzle ORM | Best DX: schema in TS, great types, good migration tool |
| Want maximum SQL control with types | Kysely | Pure query builder, no abstraction over SQL |
| Existing Knex.js codebase | Knex.js | Migration cost not worth it for established projects |
| Need Oracle or Redshift support | Knex.js | Only option with broad legacy DB support |
| Serverless / edge (minimal bundle) | Drizzle ORM | Smallest bundle size, works great at edge |
Bottom line: Drizzle ORM hits the sweet spot for most new TypeScript projects — you get the type safety of Prisma with the SQL-level control of a query builder. Kysely is the choice for SQL purists who want zero abstraction. Knex.js remains solid but its TypeScript story is weaker than the newcomers. See also: Prisma vs Drizzle vs TypeORM and Database Design Fundamentals.