5 minute read

Drizzle ORM: TypeScript-First SQL Query Builder (2026 Guide)

Quick Answer

Drizzle ORM is a lightweight TypeScript-first ORM and query builder with zero runtime dependencies. Known for its “SQL-like” syntax and exceptional performance in serverless environments, Drizzle runs natively across Node.js, Bun, Deno, Cloudflare Workers, and React Native—making it the universal choice for modern TypeScript applications.

What is Drizzle ORM?

Drizzle represents a new generation of data access tools that embraces SQL rather than hiding it. The “headless” ORM philosophy means Drizzle composes with your existing infrastructure rather than replacing it, offering type safety without the overhead of traditional ORMs.

The Headless ORM Concept

Unlike monolithic ORMs (Django ORM, Hibernate), Drizzle is split into composable pieces:

  1. Core (drizzle-orm): Lightweight runtime library for query construction
  2. Kit (drizzle-kit): CLI tool for migrations, introspection, and studio
  3. Studio: Visual data browser for development

Zero Runtime Dependencies

// Bundle size comparison
Drizzle ORM: ~7kb (minified + gzipped)
Prisma: ~100MB+ (includes Rust binary)
TypeORM: ~500kb+ (with dependencies)

This minimal footprint eliminates cold start penalties in serverless functions.

Key Features

Dual Query APIs

Drizzle uniquely offers two ways to query:

SQL-like Query Builder:

import { sql } from 'drizzle-orm';
import { users, posts } from './schema';

const result = await db
  .select()
  .from(users)
  .leftJoin(posts, eq(users.id, posts.authorId))
  .where(sql`${users.age} > 18`)
  .orderBy(desc(users.createdAt))
  .limit(10);

Relational Query Builder (RQB):

const result = await db.query.users.findMany({
  with: {
    posts: {
      where: eq(posts.published, true),
      limit: 5
    }
  }
});

Schema Definition

Drizzle uses database-specific core modules for optimal feature support:

import { pgTable, serial, text, boolean, timestamp } from 'drizzle-orm/pg-core';

export const users = pgTable('users', {
  id: serial('id').primaryKey(),
  fullName: text('full_name').notNull(),
  isActive: boolean('is_active').default(true),
  createdAt: timestamp('created_at').defaultNow(),
});

Platform Support

Drizzle runs ubiquitously across the modern computing landscape:

Environment Support Status Key Integrations
Server Full Support Node.js, Bun, Deno
Edge Full Support Cloudflare Workers, Vercel Edge
Mobile Full Support Expo, React Native (Hermes compatible)
Browser Full Support PGLite, SQL.js, DuckDB WASM

Drizzle vs Prisma

The most common comparison for decision-makers:

Feature Drizzle ORM Prisma ORM
Philosophy SQL-First (Code-First) Schema-First (DSL)
Cold Start ~0ms (Pure JS) High (Rust Binary Spawning)
Bundle Size ~7kb ~100MB+
Type Gen Inference (Instant sync) Generation (prisma generate required)
Performance Near-native driver speed Serialization overhead
Query Control Explicit Joins/SQL Implicit (Abstracted)
Migrations SQL Files (Transparent) SQL Files (Managed)
Edge Runtime Native support Requires Accelerate adapter

Drizzle vs TypeORM

Feature Drizzle ORM TypeORM
Paradigm Functional Programming Object-Oriented (Decorators)
Type Safety Strict compile-time checking Loose (runtime undefined possible)
Maintenance Active (weekly releases) Slower development velocity
Performance Optimized for serverless Legacy Node.js patterns

Drizzle vs Sequelize

Feature Drizzle ORM Sequelize
API Design Modern, chainable Callback-based, complex
TypeScript First-class citizen Afterthought (definitions separate)
Bundle Size Minimal Large with dependencies

Database Integrations

Drizzle acts as a chameleon, adapting to your database choice:

PostgreSQL

import { drizzle } from 'drizzle-orm/node-postgres';
import { pgTable, serial, text, jsonb } from 'drizzle-orm/pg-core';

const db = drizzle(postgresUrl);
// Supports jsonb, arrays, vector extensions

MySQL

import { drizzle } from 'drizzle-orm/mysql2';
import { mysqlTable, int, varchar } from 'drizzle-orm/mysql-core';

const db = drizzle(mysqlConnection);
// Optimized for high-concurrency environments

SQLite

import { drizzle } from 'drizzle-orm/better-sqlite3';
import { sqliteTable, text } from 'drizzle-orm/sqlite-core';

const db = drizzle({
  schema,
  logger: true
});
// Also supports bun:sqlite, libsql (Turso), d1 (Cloudflare)

Serverless & Edge Deployment

Drizzle excels where traditional ORMs fail:

Cloudflare Workers

import { drizzle } from 'drizzle-orm/d1';

export default {
  async fetch(request: Request, env: Env) {
    const db = drizzle(env.DB);
    const users = await db.select().from(tables.users).all();
    return Response.json(users);
  }
}

Vercel Edge

import { drizzle } from 'drizzle-orm/neon-http';

const db = drizzle(process.env.DATABASE_URL);
// HTTP mode eliminates TCP handshake overhead

React Native (Expo)

import { drizzle } from 'drizzle-orm/expo-sqlite';
import { drizzle } from 'drizzle-orm/op-sqlite';

// Hermes compatible, no Node.js polyfills needed

ORM Integrations

Drizzle integrates seamlessly with validation libraries and frameworks:

Zod Validation

import { z } from 'zod';
import { createInsertSchema } from 'drizzle-zod';

const insertUserSchema = createInsertSchema(users);
// Generates Zod schema from Drizzle table definition

Auth.js (NextAuth)

import { DrizzleAdapter } from "@auth/drizzle-adapter";

export const authOptions = {
  adapter: DrizzleAdapter(db),
  // Drizzle stores session data
};

TanStack Start / Remix

// First-class support for loaders and actions
const users = await db.select().from(tables.users).all();

Drizzle Kit & Developer Experience

CLI Commands

# Generate migration from schema
drizzle-kit generate

# Apply migrations
drizzle-kit migrate

# Introspect existing database
drizzle-kit introspect

# Open studio
drizzle-kit studio

Drizzle Studio

  • Visual GUI for browsing and editing data
  • Run locally or embed in your application
  • Real-time data inspection

Limitations

No Lazy Loading

Drizzle requires explicit fetching of relations:

// ❌ This won't work
const user = await db.query.users.findFirst({ id: 1 });
user.posts; // undefined!

// ✅ Correct approach
const user = await db.query.users.findFirst({
  where: eq(users.id, 1),
  with: { posts: true }
});

Smaller Ecosystem

While growing, Drizzle’s plugin ecosystem is smaller than TypeORM or Sequelize.

IDE Performance

In extremely large schemas (thousands of tables), TypeScript inference can tax the IDE language server.

Use Cases: Best For

  • Serverless Architectures: Zero cold start overhead
  • TypeScript Monorepos: Shared types across frontend and backend
  • Local-First Apps: PGLite and SQLite integration
  • React Native Projects: Hermes-compatible without Node.js polyfills
  • Greenfield Projects: Full utilization of Drizzle’s schema definitions

Use Cases: Avoid For

  • Non-TypeScript Projects: Type safety is the primary value proposition
  • Teams Averse to SQL: Requires SQL knowledge for complex queries
  • Enterprise Java/C# Patterns: Missing implicit behaviors like lazy loading

FAQ

Is Drizzle ORM free?

Yes, Drizzle ORM core is completely free and open source under Apache 2.0. Drizzle Studio embeddable is a paid B2B product.

Does Drizzle support Cloudflare Workers?

Yes, Drizzle has first-class support for Cloudflare Workers via drizzle-orm/d1 and the nodejs_compat flag.

Can I use Drizzle with React Native?

Yes, Drizzle supports React Native via drizzle-orm/expo-sqlite or drizzle-orm/op-sqlite with Hermes compatibility.

How does Drizzle compare to Prisma?

Drizzle prioritizes performance and SQL transparency with ~0ms cold starts. Prisma offers magical DX with generated types but has heavier runtime overhead.

Does Drizzle require code generation?

No, Drizzle uses TypeScript inference rather than code generation. Types are computed directly from your schema definitions.


Related Technologies: Prisma, PostgreSQL, Neon, PlanetScale, Supabase, Cloudflare D1

Updated: