DEV Community

Alex Spinov
Alex Spinov

Posted on

Drizzle ORM Has Free SQL Superpowers That Make Prisma Feel Bloated

Prisma generates a query engine binary. Drizzle generates zero runtime overhead — it compiles to SQL at build time and weighs just 33KB.

Why Developers Are Switching

Prisma Drizzle
Bundle size ~2MB (engine binary) 33KB
SQL knowledge needed No Yes (that is the point)
Edge runtime compatible Partial Yes (everywhere)
Migrations Auto-generated Auto-generated
Raw SQL escape hatch Awkward Native
Type safety Yes Yes (SQL-level)

Schema Definition

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

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

export const posts = pgTable("posts", {
  id: uuid("id").defaultRandom().primaryKey(),
  title: text("title").notNull(),
  content: text("content"),
  authorId: uuid("author_id").references(() => users.id),
  publishedAt: timestamp("published_at"),
});
Enter fullscreen mode Exit fullscreen mode

Queries (SQL-Like API)

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

// Select
const allUsers = await db.select().from(users);

// Where
const verified = await db.select().from(users).where(eq(users.verified, true));

// Complex filters
const result = await db.select().from(users).where(
  and(
    gt(users.age, 18),
    like(users.email, "%@gmail.com")
  )
).orderBy(desc(users.createdAt)).limit(10);

// Joins
const usersWithPosts = await db
  .select({
    userName: users.name,
    postTitle: posts.title,
    publishedAt: posts.publishedAt,
  })
  .from(users)
  .leftJoin(posts, eq(users.id, posts.authorId))
  .where(eq(users.verified, true));

// Aggregations
const stats = await db
  .select({
    authorId: posts.authorId,
    postCount: count(posts.id),
  })
  .from(posts)
  .groupBy(posts.authorId)
  .having(gt(count(posts.id), 5));
Enter fullscreen mode Exit fullscreen mode

Relational Queries (Prisma-Like API)

const usersWithPosts = await db.query.users.findMany({
  with: {
    posts: {
      where: (posts, { isNotNull }) => isNotNull(posts.publishedAt),
      orderBy: (posts, { desc }) => [desc(posts.publishedAt)],
      limit: 5,
    },
  },
  where: (users, { eq }) => eq(users.verified, true),
});
Enter fullscreen mode Exit fullscreen mode

Best of both worlds — SQL-level control with Prisma-like convenience.

Migrations

# Generate migration from schema changes
npx drizzle-kit generate

# Apply migrations
npx drizzle-kit migrate

# Push schema directly (development)
npx drizzle-kit push

# Visual studio for your database
npx drizzle-kit studio
Enter fullscreen mode Exit fullscreen mode

Drizzle Studio opens a web UI to browse and edit your data.

Works Everywhere

// PostgreSQL
import { drizzle } from "drizzle-orm/node-postgres";
const db = drizzle(process.env.DATABASE_URL);

// MySQL
import { drizzle } from "drizzle-orm/mysql2";

// SQLite
import { drizzle } from "drizzle-orm/better-sqlite3";

// Cloudflare D1
import { drizzle } from "drizzle-orm/d1";

// Neon (serverless PostgreSQL)
import { drizzle } from "drizzle-orm/neon-http";

// Turso (edge SQLite)
import { drizzle } from "drizzle-orm/libsql";
Enter fullscreen mode Exit fullscreen mode

Building data-heavy applications? I create scraping tools and API solutions. Email spinov001@gmail.com or check my Apify tools.

Top comments (0)