DEV Community

Alex Spinov
Alex Spinov

Posted on

Drizzle ORM Has a Free API: The TypeScript ORM That Feels Like Writing SQL, Not Fighting an Abstraction

ORMs promise simplicity but deliver complexity. You end up debugging the ORM instead of your queries. Drizzle takes a different approach: it gives you a TypeScript API that maps 1:1 to SQL. If you know SQL, you know Drizzle.

What Is Drizzle ORM?

Drizzle is a TypeScript ORM that mirrors SQL syntax in TypeScript. Unlike Prisma or TypeORM, Drizzle does not generate a query engine or runtime client. Your queries compile to exactly the SQL you expect, with full type safety.

The Free Tool

Drizzle is completely free and open source:

  • Zero overhead: No query engine, no runtime dependencies
  • SQL-like syntax: TypeScript API that mirrors SQL
  • Full type safety: Inferred types from your schema
  • All databases: PostgreSQL, MySQL, SQLite, Turso, Neon, PlanetScale
  • Drizzle Kit: Migration management CLI
  • Drizzle Studio: Free database browser

Quick Start

Install Drizzle:

npm install drizzle-orm postgres
npm install -D drizzle-kit
Enter fullscreen mode Exit fullscreen mode

Define your schema:

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

export const users = pgTable('users', {
  id: serial('id').primaryKey(),
  name: text('name').notNull(),
  email: text('email').notNull().unique(),
  createdAt: timestamp('created_at').defaultNow(),
});

export const posts = pgTable('posts', {
  id: serial('id').primaryKey(),
  title: text('title').notNull(),
  content: text('content'),
  published: boolean('published').default(false),
  authorId: integer('author_id').references(() => users.id),
});
Enter fullscreen mode Exit fullscreen mode

Query with SQL-like syntax:

import { drizzle } from 'drizzle-orm/postgres-js';
import { eq, and, gt, desc } from 'drizzle-orm';
import postgres from 'postgres';

const client = postgres('postgresql://...');
const db = drizzle(client);

// SELECT — feels like SQL
const allUsers = await db.select().from(users);

// WHERE with type-safe conditions
const activeUsers = await db
  .select()
  .from(users)
  .where(eq(users.email, 'test@example.com'));

// JOIN
const postsWithAuthors = await db
  .select({
    postTitle: posts.title,
    authorName: users.name,
  })
  .from(posts)
  .leftJoin(users, eq(posts.authorId, users.id))
  .where(eq(posts.published, true))
  .orderBy(desc(posts.id));

// INSERT
await db.insert(users).values({
  name: 'John',
  email: 'john@example.com',
});

// UPDATE
await db.update(users)
  .set({ name: 'Jane' })
  .where(eq(users.id, 1));
Enter fullscreen mode Exit fullscreen mode

Run migrations:

npx drizzle-kit generate
npx drizzle-kit migrate
npx drizzle-kit studio  # Opens database browser
Enter fullscreen mode Exit fullscreen mode

Why Developers Choose Drizzle

A startup migrated from Prisma to Drizzle after their Prisma Client bundle added 2MB to their serverless function. Drizzle added 50KB. Their cold start times dropped from 3 seconds to 400ms. More importantly, their developers stopped guessing what SQL Prisma was generating — with Drizzle, the TypeScript code and the generated SQL are nearly identical.

Who Is This For?

  • TypeScript developers who know SQL and want type safety without abstraction
  • Serverless developers needing a lightweight ORM (no heavy runtime)
  • Teams migrating from Prisma or TypeORM wanting more control
  • Anyone frustrated by ORMs that hide the SQL from you

Start Using Drizzle

Drizzle gives you the type safety of an ORM with the transparency of raw SQL. No runtime, no query engine, no magic.

Need help with database architecture or TypeScript backends? I build custom data solutions — reach out to discuss your project.


Found this useful? I publish daily deep-dives into developer tools and APIs. Follow for more.

Top comments (0)