Drizzle ORM Prompt Pack
What This Pack Solves
Drizzle ORM has a small but critical set of patterns that AI tools consistently get wrong: incorrect import paths for the Neon serverless driver, wrong relation syntax, misuse of drizzle-kit push vs generate+migrate, and type errors when building dynamic queries.
These prompts give Claude and Cursor the exact context to generate correct, idiomatic Drizzle code without the back-and-forth debugging cycle.
When To Use
- You're starting a new Drizzle schema from scratch
- AI keeps generating Prisma patterns in your Drizzle codebase
- You need correct relation definitions that work with
within queries - You're unsure when to use
pushvsgenerate+migrate - You need type-safe dynamic queries or transactions
Prompts
Prompt 1: Project Context Block
Use this at the start of every Drizzle-related conversation.
I'm using Drizzle ORM with Neon serverless PostgreSQL in a Next.js 15 App Router project.
Setup:
- Driver: @neondatabase/serverless (not 'pg' or 'postgres')
- DB client: import { db } from '@/lib/db' — already configured
- Schema files: src/lib/db/schema.ts (or schema/*.ts)
- Migrations: managed with drizzle-kit
Key rules:
- Use pgTable() from 'drizzle-orm/pg-core' for all table definitions
- Import { eq, and, or, desc, asc, sql } from 'drizzle-orm' for operators
When to use: Start of any conversation about your database layer.
Prompt 2: Schema Definition
I need a Drizzle schema for [describe your data model].
Requirements:
- Use pgTable() from 'drizzle-orm/pg-core'
- Primary keys: use uuid() with .defaultRandom() OR serial() — I'll tell you which
- Timestamps: createdAt and updatedAt on every table, use timestamp() with { withTimezone: true }
- updatedAt should use .$onUpdate(() => new Date())
- Foreign keys: reference the parent table column directly
- Export the table AND the inferred TypeScript types (Select and Insert variants)
Tables needed:
[describe each table and its fields, relationships, and any constraints]
Also define the relations() for each table so I can use the 'with' syntax in queries.Expected output: Complete schema with table definitions, relations, and exported TypeScript types.
Prompt 3: Querying with Relations
I need to query [describe what you want to fetch] using Drizzle's relational query API.
My schema has these relations already defined:
[paste your relations() definitions]
Requirements:
- Use db.query.[tableName].findMany() or findFirst() — not db.select()
- Include related data with the 'with' key
- Filter with the 'where' key using operators from 'drizzle-orm'
- Limit and offset for pagination if needed
- The return type should be inferred — don't write manual return type interfaces
Query goal: [describe exactly what data you need and any filters]Expected output: A typed relational query using Drizzle's query API with correct with nesting.
Prompt 4: Mutations (Insert, Update, Delete)
I need Drizzle mutations for [describe the operation].
Requirements:
- Insert: use db.insert(table).values({...}).returning()
- Update: use db.update(table).set({...}).where(eq(table.id, id)).returning()
- Delete: use db.delete(table).where(eq(table.id, id))
- Always use .returning() on insert/update so I get the created/updated record back
- Infer the insert type: type NewUser = typeof users.$inferInsert
- Wrap in try/catch — throw a typed error on constraint violations
Operation: [describe what you're inserting/updating/deleting]
Data shape: [describe the input fields and types]Expected output: Type-safe insert/update/delete with .returning() and error handling.
Prompt 5: Migrations with drizzle-kit
Explain the correct migration workflow for my Drizzle + Neon setup.
My setup:
- drizzle.config.ts is configured with dialect: 'postgresql' and Neon connection string
- Schema is in src/lib/db/schema.ts
I need to understand:
1. When to use 'pnpm drizzle-kit push' vs 'pnpm drizzle-kit generate' + 'pnpm drizzle-kit migrate'
2. How to safely apply a schema change [describe the change] to production
3. Whether this change is destructive (column removal, rename, type change)
4. What the migration SQL will look like before I run it
Schema change I need to make: [describe what you're adding/changing/removing]Expected output: Correct migration command sequence with explanation of destructive vs safe changes.
Prompt 6: Transactions and Upserts
I need [a transaction / an upsert] in Drizzle.
[For transactions]:
I need to perform multiple writes atomically:
1. [describe first operation]
2. [describe second operation]
3. [describe third operation]
If any step fails, all changes should be rolled back.
Use db.transaction(async (tx) => { ... }) — pass tx instead of db to all operations inside.
[For upserts]:
I need to insert a record if it doesn't exist, or update it if it does.
Conflict target: [describe the unique column(s)]
On conflict: [describe what fields to update]
Use db.insert(table).values({...}).onConflictDoUpdate({ target: table.column, set: {...} })Expected output: Correct transaction with rollback, or typed upsert with conflict handling.
Tuning Notes
- Always specify your driver —
@neondatabase/serverlessis not the same aspg. Wrong driver = broken serverless deployment. - Specify query API vs core — Say "use relational query API (db.query)" or "use core API (db.select)". They have different syntax and AI mixes them up.
- Paste your schema — For queries and mutations, paste the relevant table definitions. AI generates much better code when it can see the actual column names and types.
- Name your version — Drizzle changed the relations API between minor versions. Say "Drizzle ORM latest" to avoid outdated patterns.
Common Failure Modes
- Wrong import path for Neon — AI often writes
import { Pool } from 'pg'instead ofimport { neon } from '@neondatabase/serverless'. Explicitly say "Neon serverless driver." - Relations defined inside the table — Drizzle relations are defined separately with
relations(), not insidepgTable(). AI sometimes generates Prisma-style inline relations. - Missing
.returning()— AI sometimes omits.returning()on inserts, giving you no data back. Always specify this in your prompt. - Using
db.selectwhen you want relational queries — The core API (db.select().from()) doesn't support thewithsyntax. Usedb.queryfor relational fetching.