drizzle-best-practices

Guides Drizzle ORM schema design, queries, and migrations for PostgreSQL monorepos.

Updated Aug 2, 2026
One-click install
npx skills add https://github.com/leonardoacosta/skills --skill drizzle-best-practices-leonardoacosta
Or copy as Structured Prompt for Agent
Please help me install this Agent Skill.
Skill: drizzle-best-practices
Source: https://github.com/leonardoacosta/skills/tree/main/t3-stack-kit/skills/drizzle-best-practices
Command: npx skills add https://github.com/leonardoacosta/skills --skill drizzle-best-practices-leonardoacosta

SYSTEM DOCUMENTATION & REQUIREMENTS

What problem does it solve? Drizzle ORM has non-obvious behaviors—silent missing relations, misleading nullability, destructive column renames, and db:push drift—that cause data loss and production incidents in T3 Turbo + PostgreSQL (Neon) monorepos. This Skill encodes the correct patterns so agents avoid these traps. ## Core Features & Use Cases - Schema Design Rules: Primary key strategy (serial vs uuid vs cuid2), branded column types with .$type<>(), and correct pairing of foreign keys with relations(). - Query Patterns: findFirst undefined semantics, explicit with: eager loading, N+1 tradeoffs, .prepare() for hot paths, and raw SQL escape hatches. - Migration Safety: Enforces migration-file-only workflows (never db:push), multi-deploy safe column renames, zero-downtime column additions, and --custom data migrations. - Use Case: When asked to rename a column in packages/db/src/schemas/, the agent generates a multi-step migration (add nullable column, backfill, switch code, drop old column) instead of a destructive single-step rename. ## Quick Start Review my Drizzle schema changes in packages/db and generate a safe migration plan for renaming the user email column.

Frequently Asked Questions about drizzle-best-practices

High-intent search queries and answers about installing and using this skill.

FAQPage Schema
How do I safely rename a column in Drizzle ORM?

Never rename directly—Drizzle generates DROP COLUMN plus ADD COLUMN, destroying data. Instead add a new nullable column, deploy and backfill with UPDATE, switch all code to the new name, then drop the old column in a final migration.

Why does db.query with the with option return missing relations?

The with option only works when relations() is defined for the table; without it, Drizzle silently returns no joined data and no error. Always pair relations() definitions with the corresponding foreign key constraints.

Should I use drizzle-kit push or generate for schema changes?

Always use drizzle-kit generate to produce reviewable SQL migration files applied via db:migrate. db:push skips the migrations journal, can silently drop or alter columns, and collides with deploy-time migration replay causing drift.

Does findFirst in Drizzle return null or undefined?

findFirst returns undefined when no row matches, not null. Guard results with if (!user) rather than if (user === null) to handle missing records correctly.

When should I use serial, uuid, or cuid2 for primary keys in Drizzle?

Use serial for internal high-volume tables, uuid for cross-service or externally visible IDs, and cuid2 for user-facing URL-safe slugs. Note that cuid2 via $defaultFn is TypeScript-only, so raw SQL inserts must supply the value.