Using an ORM

Drizzle or Prisma — Typed Queries, No Hand-Written SQL

Using an ORM

An ORM gives you typed queries, migrations, and a pleasant API. Drizzle and Prisma are the two front-runners.

4 min read Level 2/5 #express#orm#drizzle
What you'll learn
  • Choose an ORM
  • Wire one into Express
  • Run a basic query

Raw pool.query works. An ORM gives you typed queries, schema migrations, and a nicer API. Two leaders in 2026: Drizzle and Prisma.

Drizzle

Close to SQL, TS-native:

npm install drizzle-orm pg
npm install --save-dev drizzle-kit
// src/db/schema.ts
import { pgTable, serial, text, timestamp } from "drizzle-orm/pg-core";

export const users = pgTable("users", {
  id:        serial("id").primaryKey(),
  email:     text("email").notNull().unique(),
  name:      text("name").notNull(),
  createdAt: timestamp("created_at").defaultNow(),
});
// src/db/client.ts
import { drizzle } from "drizzle-orm/node-postgres";
import { Pool } from "pg";

export const pool = new Pool({ connectionString: process.env.DATABASE_URL });
export const db = drizzle(pool);
// src/controllers/users.ts
import { db } from "../db/client.js";
import { users } from "../db/schema.js";
import { eq } from "drizzle-orm";

export async function get(req, res) {
  const [user] = await db
    .select()
    .from(users)
    .where(eq(users.id, req.validParams.id));
  if (!user) return res.status(404).json({ error: { code: "not_found" } });
  res.json({ data: user });
}

The query is type-safe — your IDE knows users.email is a column and what it returns.

Prisma

Schema-first, generated client:

npm install prisma @prisma/client
npx prisma init
// prisma/schema.prisma
model User {
  id        Int      @id @default(autoincrement())
  email     String   @unique
  name      String
  createdAt DateTime @default(now())
}
npx prisma migrate dev --name init
npx prisma generate
// src/controllers/users.ts
import { PrismaClient } from "@prisma/client";

const prisma = new PrismaClient();

export async function get(req, res) {
  const user = await prisma.user.findUnique({ where: { id: req.validParams.id } });
  if (!user) return res.status(404).json({ error: { code: "not_found" } });
  res.json({ data: user });
}

Drizzle vs Prisma

DrizzlePrisma
Schema inTS code.prisma DSL
CodegenNoYes
Bundle sizeSmallBigger
Edge runtimesYesLimited
Query styleSQL-likeObject-oriented
Learning curveIf you know SQL: easyA bit more upfront

Both are great. Pick by personal preference — for SQL-comfortable devs, Drizzle. For people who want a higher abstraction, Prisma.

Migrations

Both ship migration tools:

# Drizzle
npx drizzle-kit generate
npx drizzle-kit migrate

# Prisma
npx prisma migrate dev
npx prisma migrate deploy   # prod

Commit migrations to git. Run them as part of every deploy.

When To Skip

Tiny scripts, prototypes, learning — raw pg is fine. As soon as you have more than a handful of queries, an ORM pays back fast.

File Uploads →