DEV Community

Alex Spinov
Alex Spinov

Posted on

Drizzle ORM Has a Free Library — Here's How to Write SQL That TypeScript Actually Understands

A developer said: 'Prisma generates 10MB of client code and adds 100ms to cold starts. Drizzle generates zero — it's just TypeScript functions that map to SQL. Same type safety, zero overhead.'

What Drizzle ORM Offers

Drizzle (open source, free):

  • Zero runtime overhead — no code generation, no engine
  • SQL-like syntax — if you know SQL, you know Drizzle
  • Full type safety — inferred types from your schema
  • Any database — PostgreSQL, MySQL, SQLite, Turso, Neon, PlanetScale
  • Drizzle Kit — migrations, push, studio
  • Edge-ready — works everywhere (Cloudflare, Vercel, Bun)
  • Serverless-friendly — sub-10ms cold starts

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, text, boolean, timestamp, integer, uuid } from 'drizzle-orm/pg-core';

export const users = pgTable('users', {
  id: uuid('id').primaryKey().defaultRandom(),
  name: text('name').notNull(),
  email: text('email').notNull().unique(),
  role: text('role', { enum: ['user', 'admin'] }).default('user'),
  createdAt: timestamp('created_at').defaultNow()
});

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

Queries (SQL-Like Syntax)

import { drizzle } from 'drizzle-orm/postgres-js';
import { eq, gt, desc, and, sql, count, avg } from 'drizzle-orm';
import postgres from 'postgres';
import * as schema from './schema';

const client = postgres(process.env.DATABASE_URL!);
const db = drizzle(client, { schema });

// Select with filter
const publishedPosts = await db
  .select()
  .from(schema.posts)
  .where(eq(schema.posts.published, true))
  .orderBy(desc(schema.posts.createdAt))
  .limit(10);

// Join
const postsWithAuthor = await db
  .select({
    title: schema.posts.title,
    authorName: schema.users.name,
    authorEmail: schema.users.email
  })
  .from(schema.posts)
  .leftJoin(schema.users, eq(schema.posts.authorId, schema.users.id))
  .where(eq(schema.posts.published, true));

// Insert
const newPost = await db
  .insert(schema.posts)
  .values({ title: 'Hello Drizzle', authorId: userId })
  .returning();

// Update
await db
  .update(schema.posts)
  .set({ published: true, views: sql`${schema.posts.views} + 1` })
  .where(eq(schema.posts.id, postId));

// Delete
await db.delete(schema.posts).where(eq(schema.posts.id, postId));

// Aggregate
const stats = await db
  .select({
    authorId: schema.posts.authorId,
    postCount: count(),
    avgViews: avg(schema.posts.views)
  })
  .from(schema.posts)
  .groupBy(schema.posts.authorId);
Enter fullscreen mode Exit fullscreen mode

Relations (Query API)

// Define relations
import { relations } from 'drizzle-orm';

export const usersRelations = relations(users, ({ many }) => ({
  posts: many(posts)
}));

export const postsRelations = relations(posts, ({ one }) => ({
  author: one(users, { fields: [posts.authorId], references: [users.id] })
}));

// Query with relations
const usersWithPosts = await db.query.users.findMany({
  with: { posts: { where: eq(posts.published, true) } },
  limit: 10
});
Enter fullscreen mode Exit fullscreen mode

Migrations

# Generate migration
npx drizzle-kit generate

# Apply migration
npx drizzle-kit migrate

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

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

Drizzle vs Prisma

Drizzle Prisma
Zero codegen 10MB+ generated client
SQL-like syntax Custom query API
Sub-10ms cold start 100ms+ cold start
~30KB bundle ~600KB bundle
Edge-native Needs Accelerate for edge
No engine Requires query engine

Need data for your database? Check out my web scraping actors on Apify.

Need help with database architecture? Email me at spinov001@gmail.com.

Top comments (0)