SpikeMe
← Comparisons
Data

Drizzle vs Kysely

updated on July 14, 2026

Drizzle vs Kysely

Drizzle and Kysely compared on model (TS-schema ORM vs typed query builder), migrations, type inference, and overhead, with real npm data and a verdict by context.

FactDrizzleKysely
Current version0.45.20.29.3
Downloads/week (npm)11,394,8538,787,197
LicenseApache-2.0MIT
Bundle (gzip)8.4 kB38.7 kB
CriterionDrizzleKysely
Modellightweight ORM with a schema declared in TypeScripttyped query builder, no ORM layer
Migrationsdrizzle-kit (generate/push) from the TS schemaminimal hand-written migrator + kysely-codegen from the database
Type inferencetypes inferred straight from the TS schematypes come from a Database interface (hand-written or codegen'd)
Closeness to SQLSQL-like query builder, with relations and ORM helpersmirrors SQL almost 1:1, no ORM abstraction
Size~8.4 kB gzip~38.7 kB gzip
Ecosystem and maturity11.4M/wk, drizzle-kit and Drizzle Studio under one umbrella8.8M/wk, strict focus on building queries
Edge and serverlesspure TS with no binary, first-party serverless driverspure TS, runs on edge with the right dialect/driver

Context

The question that separates Drizzle from Kysely comes before any benchmark: do you want an ORM, or just a typed way to write SQL? Drizzle is a lightweight ORM. You declare the schema in TypeScript (pgTable, mysqlTable, etc.), and from it you get type inference, a query builder with relations, and drizzle-kit to generate and apply migrations. Kysely is not an ORM: it's a typed query builder that mirrors SQL almost 1:1. There's no schema declared as the source of truth inside the library; you supply a Database interface with the table types (by hand or generated by kysely-codegen from the database) and write selectFrom(...).select(...).where(...) the way you'd write the SQL itself.

That difference decides who owns the schema. In Drizzle, TypeScript is the source of truth: drizzle-kit diffs the schema and emits the SQL for migrations. In Kysely, the database is the source of truth: kysely-codegen introspects the tables and generates the types, and you write migrations by hand with a minimal migrator the library ships, with no generator that diffs the schema. Both are pure TypeScript with no native binary, so both run well on edge and serverless (this is where the comparison with a Rust-engine ORM stops applying). What's left as a tangible difference is package cost (about 8.4 kB gzip for Drizzle against 38.7 kB for Kysely) and reach: Drizzle pulls more downloads (11.4M/wk against 8.8M/wk) and carries drizzle-kit and Drizzle Studio under one umbrella, while Kysely stays strictly focused on building queries.

When to choose Drizzle

Drizzle makes sense when you want the guarantees of an ORM without giving up queries that read like SQL: a schema declared in one place, types inferred from it, migrations versioned by drizzle-kit, and relation helpers when the model has recurring joins.

import { pgTable, serial, text, integer } from "drizzle-orm/pg-core";
import { eq } from "drizzle-orm";

export const users = pgTable("users", {
  id: serial("id").primaryKey(),
  name: text("name").notNull(),
  teamId: integer("team_id").notNull(),
});

const rows = await db.select().from(users).where(eq(users.teamId, 1));

The users above is both the schema and the origin of the types: db.select() already knows id is number and name is string, with no manual codegen step. When the schema changes, drizzle-kit generates the matching migration, so the change history lives alongside the code. Add the relations API for recurring joins, Drizzle Studio for inspecting data, and a runtime that is just TypeScript (no binary), and you have a complete data layer that still runs on edge with no native-engine cold start. The cost is accepting an ORM layer: its own schema-definition conventions and a query builder that, SQL-like as it is, remains an abstraction on top of literal SQL.

When to choose Kysely

Kysely makes sense when you don't want an ORM, you want SQL. It gives full type-safety over queries you write yourself, in the form closest to SQL, without hiding joins, subqueries, or aggregate functions behind an object API.

import { Kysely } from "kysely";

interface Database {
  users: { id: number; name: string; team_id: number };
}

const db = new Kysely<Database>({ dialect });

const rows = await db
  .selectFrom("users")
  .select(["id", "name"])
  .where("team_id", "=", 1)
  .execute();

The Database interface is the contract: you write it by hand or let kysely-codegen generate it from the existing database. From it, each method mirrors a SQL clause, and inference follows along: the select(["id", "name"]) above narrows the type of rows to exactly those two columns, with no any and without pulling fields you didn't ask for. There are no magic relations and no intermediate engine; what you write is what runs against the database. The trade-off is that Kysely doesn't do an ORM's job: you write migrations by hand with the library's minimal migrator (there's no schema diff like drizzle-kit's), keeping the Database interface in sync with the database is your responsibility (or your codegen's, in the pipeline), and the package is larger, about 38.7 kB gzip against Drizzle's 8.4 kB.

Verdict

The axis is simple: Drizzle is an ORM, Kysely is not. If you want a data layer that owns the schema, generates migrations from it (drizzle-kit), and offers relations, Drizzle delivers all of that in a runtime that is still just TypeScript, which here weighs in its favor, including on the smaller size (8.4 kB against 38.7 kB). If you want to write SQL with full type-safety and nothing else, with no ORM abstraction between your code and the database, Kysely is the more honest tool: every query is SQL you recognize, with the safety net of types.

Because both are pure TypeScript, the runtime tiebreaker that usually decides one ORM against another doesn't show up here: the question goes back to how much abstraction over SQL you accept and who owns the schema. A team that already has a database and thinks in SQL tends to do well with Kysely plus kysely-codegen, leaving the database as the source of truth. A team starting from scratch that wants schema, migrations, and relations coming from one place finds a more complete layer in Drizzle. Swapping one for the other in a project that already works rarely pays off: the choice is one of data-access style, not correctness, and rewriting queries that already pass their tests just to change syntax is effort with no clear return.

Drizzle

Choose Drizzle if…

Choose Drizzle if you want a lightweight ORM with a TypeScript schema, drizzle-kit migrations, and relation helpers, keeping a minimal runtime for serverless.

Kysely

Choose Kysely if…

Choose Kysely if you want a query builder that mirrors SQL with full type-safety, no ORM layer, hand-controlling every generated query.

The numbers above came from the registry, with source and date. Still, this comparison is generic: the right answer depends on versions, your team and what already exists in your project.

Generate the spike for YOUR stack

Share

XLinkedIn