Home › Drizzle ORM › Drizzle ORM rules
Drizzle ORM rules
Cursor rules for Drizzle ORM with Postgres or SQLite: schema files, drizzle-kit migrations, and type-safe queries.
CursorDrizzle ORM
How to use
Save this as .cursor/rules/drizzle.mdc in your repository root, commit it, and your agent will pick it up automatically. Edit the commands to match your project.
Note: Review and test before use. Provided as is, without warranty. See Terms.
.cursor/rules/drizzle.mdcDownload ---
description: Drizzle ORM conventions
globs: ["src/db/**","drizzle.config.ts"]
alwaysApply: false
---
# Drizzle ORM
- Tables are defined in `src/db/schema.ts` (or `src/db/schema/*.ts`) with `pgTable`/`sqliteTable`. Export inferred types: `type User = typeof users.$inferSelect`, `NewUser = typeof users.$inferInsert`.
- Migrations: `npx drizzle-kit generate` after schema changes, review the SQL, then `npx drizzle-kit migrate`. Use `drizzle-kit push` only for local prototypes.
- Declare `relations()` to use the relational query API (`db.query.users.findMany({ with: { posts: true } })`); use the SQL-like builder for joins and aggregates.
- Always pass a `where` to `update` and `delete`. Use `eq`, `and`, `inArray` helpers; the `sql` template only for things the builder can't express, with values interpolated as parameters.
- Return what you need: `.returning({ id: users.id })`, `db.select({ ... })`.
- Transactions with `db.transaction(async (tx) => ...)`, using `tx` inside.
- Indexes and unique constraints in the table's third argument; timestamps with `defaultNow()` and `$onUpdate`.
- Validate inputs with `drizzle-zod` (`createInsertSchema`) or zod schemas derived from the table.
## Don't
- Don't string-concatenate SQL or call `sql.raw()` with user input.
- Don't edit generated migration files after they've been applied anywhere.
## Done when
`drizzle-kit check`, typecheck and tests pass.