Skip to content
cccskills
FreePublished on GitHub

drizzle-pro

Drizzle ORM guidance — schema-as-code, relational queries, migrations, and SQL-first TypeScript data access.

The English summary is being prepared. Showing the original description.

Works withPostgreSQL
See how to install

Files included (1)

  • SKILL.md7.0 KB

SKILL.md (original)

Review the instructions the agent will receive before you install.

Overview

Drizzle is a TypeScript ORM that stays close to SQL: you define tables as code, write queries with a relational query builder that mirrors SQL structure, and get full type safety without a schema DSL or heavy runtime. If Prisma feels like a layer above SQL, Drizzle feels like SQL with types.

That closeness is the point — and the responsibility. Drizzle won't hide query behavior from you, which means you need to understand joins, indexes, and transactions yourself. This skill covers Drizzle's schema-as-code model, its relational query API, migration workflow, and the SQL-first patterns that make it shine.

When to use

  • Choosing a lightweight, SQL-first TypeScript ORM.
  • Defining Drizzle schemas (tables, relations, indexes).
  • Writing relational queries without N+1 problems.
  • Running Drizzle migrations (drizzle-kit workflow).
  • Using Drizzle with serverless/edge databases (Neon, PlanetScale, Turso, D1).
  • Dropping to raw SQL for complex queries.
  • Migrating from Prisma/TypeORM to Drizzle.

Core concepts

  • Schema as TypeScript. Tables are defined with pgTable/mysqlTable/sqliteTable — plain code, versioned in git, refactorable with your IDE. No DSL to learn, no codegen step for the schema itself.
  • Two query APIs. The relational query builder (db.query.users.findMany({ with: { posts: true } })) for nested relational reads, and the SQL-like core API (db.select().from(users).where(...)) for everything else. Learn both; use each where it fits.
  • Relations are explicit. defineRelations (or the relations helper) declares how tables join; the relational API uses them to build joins for you. Explicit relations mean no magic — and no surprise queries.
  • Migrations via drizzle-kit. drizzle-kit generate diffs schema code into SQL migrations; drizzle-kit migrate applies them. Review generated SQL like any other migration; snapshot-based diffing can surprise on renames.
  • SQL-first, always. Every Drizzle query maps predictably to SQL. When the builder can't express something, sql template literals drop you to raw SQL with parameterization built in — no string concatenation.
  • Dialect differences matter. Postgres, MySQL, and SQLite have different types, index kinds, and capabilities. Drizzle exposes them honestly; write dialect-aware schema code and test against the real database.
  • Transactions. db.transaction(async (tx) => {...}) — same rules as everywhere: short, ordered row access, no network calls inside.
  • Prepared statements. Drizzle supports prepared queries for hot paths; use them for repeated queries where parse overhead matters.
  • Indexes and constraints in code. index(), uniqueIndex(), foreign keys with onDelete actions — declared alongside the table, migrated with everything else.
  • Edge/serverless friendly. Zero-dependency, tiny bundle, HTTP-based drivers for Neon/PlanetScale/Turso — Drizzle was built for the serverless world where Prisma's engine is heavy.
  • No magic N+1 hiding. The relational API generates joins (not per-row queries) for with clauses — understand which API you're using and what SQL it emits.
  • Zod integration. drizzle-zod generates Zod schemas from table definitions — one source of truth for DB schema and API validation.
  • Seeding. Plain scripts using the same client; idempotent seeds, environment-gated.
  • Introspection. drizzle-kit pull reverse-engineers existing databases for brownfield adoption.

Practical workflow

  1. Define tables as code. One module per domain; declare columns, indexes, and relations together.
    export const orders = pgTable("orders", {
      id: uuid("id").primaryKey().defaultRandom(),
      status: text("status").notNull().default("pending"),
      total: numeric("total", { precision: 10, scale: 2 }).notNull(),
      createdAt: timestamp("created_at").defaultNow().notNull(),
    }, (t) => [index("orders_status_created_idx").on(t.status, t.createdAt)]);
    
  2. Declare relations. Map the joins once so the relational API can use them everywhere.
    export const ordersRelations = defineRelations(orders, (r) => ({
      items: r.many.orderItems,
      customer: r.one.customers, { from: r.customerId, to: r.customers.id },
    }));
    
  3. Generate and review migrations. drizzle-kit generate then read the SQL — especially renames, which the differ may express as drop/add. Fix destructive diffs before applying.
  4. Query relationally for reads. db.query.orders.findMany({ with: { items: true }, where, orderBy, limit }) — nested reads as joins, typed end to end.
    • For complex reporting, switch to the core API or sql — don't fight the relational API into shapes it wasn't built for.
  5. Use the core API for writes and complex filters. db.insert/update/delete with where clauses; onConflictDoUpdate for upserts; returning clauses to get rows back.
    const [order] = await db.insert(orders)
      .values({ status: "paid", total: "99.99" })
      .returning({ id: orders.id });
    
  6. Wrap multi-step writes in transactions. Short, ordered, no I/O inside — the universal rules apply.
  7. Validate at the boundary. drizzle-zod schemas for API input; the DB schema and the API schema stay in sync by construction.
  8. Test against the real dialect. SQLite in tests while Postgres runs in prod hides real behavior; use containers (or a cheap hosted branch) for integration tests.

Common pitfalls

  • Rename expressed as drop/add — the differ can't always tell; review generated SQL and hand-write renames with sql when needed.
  • Using the wrong query API — forcing reporting queries through the relational API; switch to core/sql for aggregations and complex joins.
  • Missing indexes — declaring tables without indexes for hot filter/join columns; add them in the table definition.
  • N+1 in application code — looping queries instead of one relational fetch; fetch nested data in a single query.
  • SQLite/Postgres drift — testing on one dialect, deploying another; type and behavior differences will bite.
  • Long transactions — same universal rule: short, ordered, no network calls inside.
  • Unparameterized sql — interpolating values into sql fragments instead of using its parameter binding; that's SQL injection.
  • No migration review — auto-applying generated migrations; always read the SQL, especially on existing tables.
  • Ignoring connection limits — serverless HTTP drivers vs pooled TCP drivers; pick the driver for your runtime and set limits.
  • Schema code sprawl — one giant schema file; split by domain like any other code.
  • Forgetting onDelete actions — default restrict behavior surprising deletes; declare referential actions explicitly.
  • Returning full rows from APIs — select only needed columns; the builder makes projection easy, so use it.

Reviews

No reviews yet. Tell others what you thought.

Comments

No login needed. Share how it worked for you, ask a question, or note where it did not run.

No comments yet. Be the first to write one.

Comments are published right away. Do not include personal information such as email addresses or phone numbers. Up to 2 URLs.

0 / 1,000 characters

This form is protected by reCAPTCHA, and the Google Privacy Policy and Terms of Service apply.

More skills from this repository

Master 1Password: vaults, Watchtower, passkeys, SSH agent, CLI, and family/team administration. Use when getting full value from 1Password personally or administering it for others.

The English summary is being prepared. Showing the original description.

aicodedecode/awesome-muse-skills28Updated Oct 10, 2026

Create 3D visuals with modeling, texturing, lighting, rendering, and optimization for web and product.

The English summary is being prepared. Showing the original description.

aicodedecode/awesome-muse-skills28Updated Oct 10, 2026

Create 3D web experiences: scene setup, models, materials, lighting, animation, scroll-driven scenes, and performance budgets. Use when adding 3D to websites beyond basic demos.

The English summary is being prepared. Showing the original description.

aicodedecode/awesome-muse-skills28Updated Oct 10, 2026

Writing abstracts that get papers read — structured content, the 5-sentence core, and journal-specific constraints.

The English summary is being prepared. Showing the original description.

aicodedecode/awesome-muse-skills28Updated Oct 10, 2026

Learn effectively from courses and academies: choosing programs, studying actively, and converting courses into skills. Use when investing time/money in structured learning.

The English summary is being prepared. Showing the original description.

aicodedecode/awesome-muse-skills28Updated Oct 10, 2026

Audit designs for accessibility with WCAG checklists covering color, type, focus, motion, and content.

The English summary is being prepared. Showing the original description.

aicodedecode/awesome-muse-skills28Updated Oct 10, 2026

See all skills by aicodedecode

Report a problem with this skill