Drizzle ORM enters the TypeScript ORM landscape with a refreshingly honest pitch: if you know SQL, you already know Drizzle. In a world where ORMs have traditionally tried to abstract away the database — hiding SQL behind object-oriented patterns, query methods, and proprietary DSLs — Drizzle takes the opposite approach. It gives you a SQL-like query builder that compiles to exactly the SQL you expect, with full TypeScript type safety inferred directly from your schema definition. No code generation step, no magic, no surprises.
The schema definition in Drizzle is pure TypeScript. You define your tables using TypeScript functions that mirror SQL DDL statements. A users table is defined with pgTable('users', { ... }), columns are defined with functions like text(), integer(), boolean(), timestamp(), and relationships are defined with references() pointing to other tables. The schema reads like annotated SQL, which means any developer who understands database design can read and write Drizzle schemas immediately.
Type inference is where Drizzle's approach pays off beautifully. Because the schema is defined in TypeScript, Drizzle can infer the types of query results automatically. When you select from a table, the result type matches the columns you selected. When you join tables, the result type includes both tables' columns. When you use conditions, the types ensure you are comparing compatible values. All of this happens without a separate code generation step — you change the schema, and the types update instantly. Compared to Prisma, which requires running prisma generate after schema changes, this immediate feedback loop is noticeably more productive.
The query builder follows SQL semantics closely. SELECT becomes db.select(), WHERE becomes .where(), JOIN becomes .innerJoin() or .leftJoin(), ORDER BY becomes .orderBy(), and GROUP BY becomes .groupBy(). The API is chainable and compositional — you can build queries incrementally, store partial queries in variables, and compose them into complex operations. For developers who think in SQL, this API feels natural and predictable.
Drizzle also offers a Relational Query API for developers who prefer a more ORM-like interface. Instead of writing explicit joins, you can define relations between tables and query them with an include-style syntax: db.query.users.findMany({ with: { posts: true } }). This API is convenient for common patterns like fetching a user with their posts, comments, and profile. It generates efficient SQL under the hood, avoiding the N+1 query problem that plagues naive ORM implementations.
Performance is a core Drizzle value. The query builder has essentially zero runtime overhead — it is a thin layer that constructs SQL strings and passes them to your database driver. There is no query engine, no runtime type checking, no middleware layer between your code and the database. The SQL that Drizzle generates is exactly what you would write by hand. This makes Drizzle the fastest TypeScript ORM in benchmarks and the most predictable in production — the query you see in your code is the query that runs on your database.