DEV Community

Alex Spinov
Alex Spinov

Posted on

Drizzle ORM Has a Free API — The TypeScript ORM That Feels Like SQL

TL;DR

Drizzle ORM is a TypeScript-first ORM that generates SQL you can actually read. Zero runtime overhead, full type safety, and it works with PostgreSQL, MySQL, SQLite, and serverless databases.

What Is Drizzle?

Drizzle ORM is SQL-like by design:

  • SQL-like syntax — if you know SQL, you know Drizzle
  • Zero overhead — thin SQL wrapper, no query builder bloat
  • Full type safety — schema-to-TypeScript type inference
  • Serverless ready — works with Neon, PlanetScale, Turso, D1
  • Migrations — automatic migration generation
  • Drizzle Studio — visual database browser
  • Free — Apache 2.0

Quick Start

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

Define Schema

// src/db/schema.ts
import { pgTable, serial, text, timestamp, integer, boolean } from "drizzle-orm/pg-core";

export const users = pgTable("users", {
  id: serial("id").primaryKey(),
  name: text("name").notNull(),
  email: text("email").notNull().unique(),
  age: integer("age"),
  active: boolean("active").default(true),
  createdAt: timestamp("created_at").defaultNow(),
});

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

Queries (SQL-like)

import { drizzle } from "drizzle-orm/postgres-js";
import postgres from "postgres";
import { users, posts } from "./schema";
import { eq, gt, like, and, desc, count } from "drizzle-orm";

const sql = postgres(process.env.DATABASE_URL!);
const db = drizzle(sql);

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

// WHERE
const activeUsers = await db
  .select()
  .from(users)
  .where(and(eq(users.active, true), gt(users.age, 18)));

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

// INSERT
const newUser = await db
  .insert(users)
  .values({ name: "Alice", email: "alice@example.com", age: 30 })
  .returning();

// UPDATE
await db
  .update(users)
  .set({ active: false })
  .where(eq(users.id, 1));

// DELETE
await db.delete(users).where(eq(users.id, 1));

// Aggregations
const stats = await db
  .select({
    total: count(),
    avgAge: avg(users.age),
  })
  .from(users)
  .where(eq(users.active, true));
Enter fullscreen mode Exit fullscreen mode

Migrations

// drizzle.config.ts
import { defineConfig } from "drizzle-kit";

export default defineConfig({
  schema: "./src/db/schema.ts",
  out: "./drizzle",
  dialect: "postgresql",
  dbCredentials: {
    url: process.env.DATABASE_URL!,
  },
});
Enter fullscreen mode Exit fullscreen mode
# Generate migration
npx drizzle-kit generate

# Apply migration
npx drizzle-kit migrate

# Open Drizzle Studio (visual DB browser)
npx drizzle-kit studio
Enter fullscreen mode Exit fullscreen mode

Serverless (Neon, Turso, D1)

// Neon Serverless
import { neon } from "@neondatabase/serverless";
import { drizzle } from "drizzle-orm/neon-http";

const sql = neon(process.env.DATABASE_URL!);
const db = drizzle(sql);

// Turso (LibSQL)
import { createClient } from "@libsql/client";
import { drizzle } from "drizzle-orm/libsql";

const client = createClient({ url: "libsql://...", authToken: "..." });
const db = drizzle(client);

// Cloudflare D1
import { drizzle } from "drizzle-orm/d1";
const db = drizzle(env.DB);
Enter fullscreen mode Exit fullscreen mode

Drizzle vs Prisma vs TypeORM

Feature Drizzle Prisma TypeORM
Syntax SQL-like Custom DSL OOP
Bundle size 35 KB 2+ MB 500 KB+
Serverless Perfect Adapter needed Poor
Raw SQL Easy $queryRaw QueryBuilder
Type safety Full inference Generated Decorators
Migrations Auto-generate Auto-generate Auto/manual
Edge runtime Yes Limited No

Resources


Storing scraped web data? My Apify tools extract structured data from any website — load it into your database with Drizzle ORM for type-safe data pipelines. Questions? Email spinov001@gmail.com

Top comments (0)