Database ORMs
Comparing TypeScript ORMs and query builders for modern web apps. Type safety, migration tooling, bundle size, serverless cold starts, and how well AI assistants generate code with each.
← Back to Reference HubA TypeScript ORM that mirrors SQL semantics rather than hiding them. Schemas are TypeScript files; queries read like SQL with type safety on tables, columns, and joins. Zero runtime dependencies, ~7.4 KB min+gzip, designed from day one for serverless and edge runtimes.
- Bundle: ~7.4 KB min+gzip, ~280 KB unpacked — orders of magnitude smaller than Prisma
- Runtimes: Node.js, Bun, Deno, Cloudflare Workers, Vercel Functions, browsers, any edge runtime
- Databases: PostgreSQL, MySQL, SQLite, plus serverless drivers for Neon, Turso, PlanetScale, Supabase, Cloudflare D1
- Drizzle Kit: CLI for SQL migration generation from schema diffs
- Drizzle Studio: Visual database explorer that runs locally
- Advanced features: Set operations, generated columns, batch caching, dynamic query building, read replicas
- Two query styles: SQL-like query builder for full control, plus a relational queries API for object-graph fetches
Limitations: Steeper learning curve than Prisma if you're not already comfortable with SQL semantics. Smaller community and tutorial corpus than Prisma. Fewer integrations with admin/dashboard tools. Migration generation occasionally needs manual cleanup for complex column transformations.
The most polished schema-first TypeScript ORM. You write a schema.prisma declarative file, run prisma generate, and get a fully typed, ergonomic client. Prisma 7 (released November 19, 2025) replaced the Rust query engine with a TypeScript implementation, dramatically reducing bundle size and cold-start cost — the historic case against Prisma in serverless environments.
- Prisma 7 changes: Rust-free TypeScript runtime; bundle dropped from ~14 MB (7 MB gzipped) to ~1.6 MB (600 KB gzipped); 3.4× faster on findMany over 25K rows; 70% faster type checks; 98% fewer types evaluated per schema
- Generated code: Now lives outside node_modules — better caching and review
- Dynamic config: New prisma.config.ts separates project config from data schema
- Databases: PostgreSQL, MySQL, MariaDB, SQLite, MongoDB, CockroachDB, Microsoft SQL Server
- Tooling: Prisma Studio (GUI), Prisma Migrate (declarative migrations), Prisma Accelerate (managed connection pooling + caching)
- Documentation: Best-in-class — Prisma docs are the gold standard among ORMs
Limitations: Even after the Rust removal, the developer-experience trade is "Prisma owns your data layer." Schema language is bespoke (not SQL); migrations are declarative (not imperative SQL files you can hand-edit). Dropping below the abstraction is awkward. Pre-7 cold-start horror stories are still in the wild — older blog posts about Prisma + Lambda no longer reflect reality.
A pure TypeScript query builder with the strongest type inference in the ecosystem. Not really an ORM — you bring your own schema definitions and migration tool. What you get is autocomplete and type-checking on every column, alias, and join, including subqueries and CTEs. Pronounced "Key-Seh-Lee."
- Type system: Best-in-class — result types narrow correctly across joins, aliases, subqueries, with-statements, window functions
- Bundle: Lightweight, no runtime engine
- Runtimes: Node.js, Deno, Bun, Cloudflare Workers, browsers
- Databases: PostgreSQL, MySQL, SQLite via official dialects; community dialects for D1, Planetscale, Neon, etc.
- SQL features: Joins, subqueries, CTEs, window functions, aggregates, raw SQL escape hatches, transactions, DDL
- Used by: Deno, Maersk, Cal.com
- Migrations: Built-in migration runner with up/down TypeScript files
Limitations: No schema-from-code — you describe your tables/columns in a TypeScript interface and keep it in sync with the actual schema yourself (or use a generator like kysely-codegen). No relations API; you write joins explicitly. No GUI. Smaller community than Drizzle or Prisma; fewer tutorials.
Heritage TypeScript ORM that follows Hibernate / Entity Framework conventions. Models are classes with decorators; the ORM resolves relationships, lazy-loads, and handles cascade behavior. Supports both Active Record and Data Mapper patterns — rare among Node ORMs. After a leadership transition in late 2024 (Michael Bromley and David Hoeck under Elevantiq), maintenance is active again: 8 patch releases through 2025, 575 PRs merged, 2,300+ issues closed, and **TypeORM v1.0.0 shipped 2026-05-19**.
- Decorator-driven entities: @Entity, @Column, @OneToMany, etc. — familiar to Java/.NET developers
- Two patterns: Active Record (User.find()) or Data Mapper (userRepository.find())
- Databases: PostgreSQL, MySQL, MariaDB, SQLite, Microsoft SQL Server, Oracle, MongoDB, plus more via drivers
- Migrations: Generated from entity diffs; usable but less polished than Drizzle Kit or Prisma Migrate
- NestJS integration: First-class via @nestjs/typeorm — the default ORM for many NestJS codebases
- Maturity: Predates Prisma and Drizzle; large existing-codebase footprint
Limitations: Type inference is weaker than Prisma, Drizzle, or Kysely — you'll occasionally fight TypeScript on relations. Decorator metadata requires experimentalDecorators + emitDecoratorMetadata, which complicates some build setups (Bun, esbuild without plugins). Larger bundle and slower cold starts than Drizzle/Prisma 7. Post-v1.0.0 (May 2026) the historical 'spotty maintenance' framing no longer applies, but the legacy decorator-heavy API still feels heavy compared to modern alternatives.
The classic JavaScript ORM — predates TypeScript by years. Define models with field types and associations, get an Active Record-style API (User.findAll(), user.save()). Still ubiquitous in older Node codebases.
- Databases: PostgreSQL, MySQL, MariaDB, SQLite, Microsoft SQL Server, Snowflake, Db2
- Production version: v6 (stable, JavaScript-first with TypeScript types added)
- Next major: v7 has been in alpha for years — 48+ alpha releases, no beta as of early 2026
- Migrations: CLI-driven via sequelize-cli
- Hooks & lifecycle events: Rich set of before/after hooks on save, create, destroy
- Validations: Built-in field validators
Limitations: TypeScript support feels bolted on rather than native — types are accurate-ish but not as ergonomic as Prisma, Drizzle, or Kysely. v7 perpetual-alpha is a real signal: starting a new TypeScript-first project on Sequelize in 2026 is hard to defend. Better choice for teams already on Sequelize v6 with a working app, where migration cost outweighs benefit.
Skip the ORM and write SQL directly. Modern drivers like postgres.js (Porsager) make this safe via tagged template literals that auto-parameterize values. Knex.js sits a bit higher as a chainable query builder. You give up code-level type safety and migrations tooling, but you keep absolute control and zero abstraction overhead.
- postgres.js: Tagged-literal API, sql`select * from users where id = ${id}`, automatic parameterization, fastest fully-featured Postgres client for Node/Bun/Deno/Workers
- node-postgres (pg): Older, more conservative, stable — the historical default
- Knex.js: Mature SQL query builder with migration tool and seed runner; pre-Kysely standard
- sqltyper / SafeQL / Squid: Tools that generate TypeScript types from your raw SQL strings against a real database, giving you type safety without an ORM
- Migrations: Roll your own with node-pg-migrate, Knex migrations, or hand-written SQL files run via psql
- Bundle: Smallest possible — just the driver
Limitations: No schema-derived types unless you wire up a generator. No automatic migration drift detection. Refactors that touch column names break silently unless you have integration tests or codegen. Not the right call for teams that need to onboard mid-level developers quickly. Best paired with PostgreSQL only — multi-database portability is harder without an ORM's dialect abstraction.
| Capability | Drizzle | Prisma 7 | Kysely | TypeORM | Sequelize | Raw SQL |
|---|---|---|---|---|---|---|
| Type Safety | ||||||
| Schema-derived types | Yes (TS schema) | Yes (generated) | Manual interfaces | Decorator-driven | Bolted on | Codegen needed |
| Query result narrowing | Excellent | Excellent | Best-in-class | Decent | Weak | None by default |
| Join / subquery types | Strong | Strong (via include) | Strongest | Decent | Weak | None by default |
| Compile-time SQL check | Schema-level | Schema-level | Full query | No | No | Via SafeQL/sqltyper |
| Migration Tooling | ||||||
| Auto-generate migrations | Drizzle Kit (SQL diffs) | Prisma Migrate (declarative) | Manual TS files | From entity diffs | CLI generator | DIY |
| Migration format | SQL files (editable) | Declarative | TypeScript | TypeScript | JavaScript / SQL | SQL files |
| Schema introspection | Yes | Yes (db pull) | kysely-codegen | Yes | Yes | N/A |
| Visual schema editor | Drizzle Studio | Prisma Studio | No | No | No | No |
| Performance & Bundle Size | ||||||
| Bundle size (min+gzip) | ~7.4 KB | ~600 KB (v7) | Small | Larger | Larger | Driver-only |
| Runtime dependencies | 0 | Few (post-Rust) | 0 (driver brings own) | Several | Several | Driver-only |
| Cold start impact | Negligible | Low (v7) | Negligible | Moderate | Moderate | Negligible |
| Query overhead | Minimal | Low (v7) | Minimal | Moderate | Moderate | Driver only |
| Serverless & Edge | ||||||
| Cloudflare Workers | First-class | Supported (v7) | First-class | Difficult | Difficult | postgres.js works |
| Vercel Functions / Lambda | Excellent | Good (v7) | Excellent | Heavy | Heavy | Excellent |
| Bun / Deno | Yes | Yes (v7) | Yes | Bun OK, decorator quirks | Partial | Native |
| HTTP-driver friendly (Neon, D1) | Yes | Yes | Yes | No | No | Yes |
| Database Support | ||||||
| PostgreSQL | Yes | Yes | Yes | Yes | Yes | Yes |
| MySQL / MariaDB | Yes | Yes | Yes | Yes | Yes | mysql2 driver |
| SQLite / libSQL / Turso | First-class | Yes | Yes | Yes | Yes | better-sqlite3 |
| Microsoft SQL Server | Yes (official, 1.0 beta) | Yes | Yes | Yes | Yes | tedious driver |
| MongoDB | No | Yes | No | Yes | No | N/A |
| Learning Curve & Community | ||||||
| Beginner-friendliness | Need SQL fluency | Easiest start | SQL fluency | Familiar to OOP devs | Documented patterns | Steepest |
| Documentation quality | Strong | Best-in-class | Good | Patchy | Good | Driver docs |
| Stack Overflow / tutorials | Growing fast | Largest | Smaller | Substantial | Substantial (legacy) | SQL is universal |
| Active maintenance | Very active | Very active | Active | Active (v1.0.0 May 2026) | v6 only; v7 stalled | Driver-dependent |
| AI-Friendliness (LLM Code Gen) | ||||||
| LLM training-data coverage | Strong (2024–2026) | Largest corpus | Modest | Strong (legacy) | Largest legacy corpus | SQL is universal |
| Generated-code accuracy | High (SQL maps cleanly) | High (after v7 update) | High (typed builder) | Variable | Variable | Highest (plain SQL) |
| Schema-aware suggestions | TS schema = LLM context | .prisma file = context | Interface = context | Decorators = context | Models = context | Need to paste schema |
| Refactor safety with AI | High (TS catches drift) | High (regen on change) | High (typed) | Decent | Low (TS gaps) | Low without codegen |
Our Recommendation
For most new TypeScript projects we'd build today, the answer is Drizzle — SQL-first semantics, tiny bundle, first-class serverless support, hand-editable migrations, and excellent AI-assist behavior because schema and queries sit in the same TypeScript files. Prisma 7 is the right call when team familiarity, multi-database portability, or polished tooling matter more than bundle size; the post-Rust 2026 redesign closed the historical serverless gap. Kysely is the senior-team pick when you want pure type safety without an ORM mental model. Raw SQL via postgres.js is increasingly defensible for small Postgres-only teams that value control, especially paired with a generator like SafeQL for compile-time query checks. Avoid starting new projects on Sequelize v7 unless you're extending an existing codebase; TypeORM is again defensible post-v1.0.0 (May 2026), particularly in NestJS shops.