Why this starter uses Drizzle instead of Prisma
Both are good. Here's the specific tradeoff that made Drizzle the default for a starter meant to be read, not just run.
Prisma and Drizzle solve the same problem well. The choice here came down to one thing: what the schema looks like when you open the file.
Plain SQL you can actually read
Drizzle's schema is TypeScript that compiles to the SQL you'd have written by hand:
export const user = pgTable("user", {
id: text("id").primaryKey(),
email: text("email").notNull().unique(),
role: text("role", { enum: ["user", "admin"] }).notNull().default("user"),
});No custom DSL, no generated client to regenerate after every edit, no schema file that only a bundler-aware tool can parse. grep still works. That matters a lot in a starter meant to be forked, read end-to-end, and modified by someone who's never seen the codebase before.
Migrations you can read in a PR
npm run db:generate # writes drizzle/NNNN_name.sql
npm run db:migrate # applies pending migrationsThe generated .sql file is the actual diff — reviewable in a pull request the same way application code is, not a binary lockfile you trust blindly.
Where Prisma still wins
Prisma's relation API and its Studio GUI are genuinely nicer for deeply nested queries and non-technical schema browsing. If your team is bigger than one and half of it isn't comfortable in SQL, that tradeoff might flip back in Prisma's favor — this starter's choice isn't a universal claim, just the right default for this shape of project.