Agent skill
postgres-drizzle
Proactively apply when creating APIs, backends, or data models. Triggers on PostgreSQL, Postgres, Drizzle, database, schema, tables, columns, indexes, queries, migrations, ORM, relations, joins, transactions, SQL, drizzle-kit, connection pooling, N+1, JSONB, RLS. Use when writing database schemas, queries, migrations, or any database-related code. PostgreSQL and Drizzle ORM best practices.
Install this agent skill to your Project
npx add-skill https://github.com/ccheney/robust-skills/tree/main/skills/postgres-drizzle
SKILL.md
PostgreSQL + Drizzle ORM
Type-safe database applications with PostgreSQL 18 and Drizzle ORM.
Essential Commands
npx drizzle-kit generate # Generate migration from schema changes
npx drizzle-kit migrate # Apply pending migrations
npx drizzle-kit push # Push schema directly (dev only!)
npx drizzle-kit studio # Open database browser
Quick Decision Trees
"How do I model this relationship?"
Relationship type?
├─ One-to-many (user has posts) → FK on "many" side + relations()
├─ Many-to-many (posts have tags) → Junction table + relations()
├─ One-to-one (user has profile) → FK with unique constraint
└─ Self-referential (comments) → FK to same table
"Why is my query slow?"
Slow query?
├─ Missing index on WHERE/JOIN columns → Add index
├─ N+1 queries in loop → Use relational queries API
├─ Full table scan → EXPLAIN ANALYZE, add index
├─ Large result set → Add pagination (limit/offset)
└─ Connection overhead → Enable connection pooling
"Which drizzle-kit command?"
What do I need?
├─ Schema changed, need SQL migration → drizzle-kit generate
├─ Apply migrations to database → drizzle-kit migrate
├─ Quick dev iteration (no migration) → drizzle-kit push
└─ Browse/edit data visually → drizzle-kit studio
Directory Structure
src/db/
├── schema/
│ ├── index.ts # Re-export all tables
│ ├── users.ts # Table + relations
│ └── posts.ts # Table + relations
├── db.ts # Connection with pooling
└── migrate.ts # Migration runner
drizzle/
└── migrations/ # Generated SQL files
drizzle.config.ts # drizzle-kit config
Schema Patterns
Basic Table with Timestamps
export const users = pgTable('users', {
id: uuid('id').primaryKey().defaultRandom(),
email: varchar('email', { length: 255 }).notNull().unique(),
createdAt: timestamp('created_at').defaultNow().notNull(),
updatedAt: timestamp('updated_at').defaultNow().notNull(),
});
Foreign Key with Index
export const posts = pgTable('posts', {
id: uuid('id').primaryKey().defaultRandom(),
userId: uuid('user_id').notNull().references(() => users.id),
title: varchar('title', { length: 255 }).notNull(),
}, (table) => [
index('posts_user_id_idx').on(table.userId), // ALWAYS index FKs
]);
Relations
export const usersRelations = relations(users, ({ many }) => ({
posts: many(posts),
}));
export const postsRelations = relations(posts, ({ one }) => ({
author: one(users, { fields: [posts.userId], references: [users.id] }),
}));
Query Patterns
Relational Query (Avoid N+1)
// ✓ Single query with nested data
const usersWithPosts = await db.query.users.findMany({
with: { posts: true },
});
Filtered Query
const activeUsers = await db
.select()
.from(users)
.where(eq(users.status, 'active'));
Transaction
await db.transaction(async (tx) => {
const [user] = await tx.insert(users).values({ email }).returning();
await tx.insert(profiles).values({ userId: user.id });
});
Performance Checklist
| Priority | Check | Impact |
|---|---|---|
| CRITICAL | Index all foreign keys | Prevents full table scans on JOINs |
| CRITICAL | Use relational queries for nested data | Avoids N+1 |
| HIGH | Connection pooling in production | Reduces connection overhead |
| HIGH | EXPLAIN ANALYZE slow queries |
Identifies missing indexes |
| MEDIUM | Partial indexes for filtered subsets | Smaller, faster indexes |
| MEDIUM | UUIDv7 for PKs (PG18+) | Better index locality |
Anti-Patterns (CRITICAL)
| Anti-Pattern | Problem | Fix |
|---|---|---|
| No FK index | Slow JOINs, full scans | Add index on every FK column |
| N+1 in loops | Query per row | Use with: relational queries |
| No pooling | Connection per request | Use @neondatabase/serverless or similar |
push in prod |
Data loss risk | Always use generate + migrate |
| Storing JSON as text | No validation, bad queries | Use jsonb() column type |
Reference Documentation
| File | Purpose |
|---|---|
| references/SCHEMA.md | Column types, constraints |
| references/QUERIES.md | Operators, joins, aggregations |
| references/RELATIONS.md | One-to-many, many-to-many |
| references/MIGRATIONS.md | drizzle-kit workflows |
| references/POSTGRES.md | PG18 features, RLS, partitioning |
| references/PERFORMANCE.md | Indexing, optimization |
| references/CHEATSHEET.md | Quick reference |
Resources
Drizzle ORM
- Official Documentation: https://orm.drizzle.team
- GitHub Repository: https://github.com/drizzle-team/drizzle-orm
- Drizzle Kit (Migrations): https://orm.drizzle.team/kit-docs/overview
PostgreSQL
- Official Documentation: https://www.postgresql.org/docs/
- SQL Commands Reference: https://www.postgresql.org/docs/current/sql-commands.html
- Performance Tips: https://www.postgresql.org/docs/current/performance-tips.html
- Index Types: https://www.postgresql.org/docs/current/indexes-types.html
- JSON Functions: https://www.postgresql.org/docs/current/functions-json.html
- Row Level Security: https://www.postgresql.org/docs/current/ddl-rowsecurity.html
Recommended Agent Skills
Expand your agent's capabilities with these related and highly-rated skills.
slack-mrkdwn
Proactively apply when generating any Slack text content, chat.postMessage text fields, or text objects with type "mrkdwn". Triggers on mrkdwn, Slack formatting, Slack markdown, Slack bold, Slack italic, Slack link syntax, Slack mentions, Slack date formatting, Slack escaping, Slack text object, verbatim, plain_text, Slack mrkdwn vs markdown, Slack blockquote, Slack code block, Slack strikethrough, Slack user mention, Slack channel mention, Slack emoji, link_names, auto-parsing. Use when formatting Slack message text, writing mrkdwn strings, constructing text objects, escaping user content for Slack, adding mentions or date formatting to messages, or debugging text rendering issues. Slack mrkdwn text formatting syntax for messages, text objects, and attachments.
clean-ddd-hexagonal
Proactively apply when designing APIs, microservices, or scalable backend structure. Triggers on DDD, Clean Architecture, Hexagonal, ports and adapters, entities, value objects, domain events, CQRS, event sourcing, repository pattern, use cases, onion architecture, outbox pattern, aggregate root, anti-corruption layer. Use when working with domain models, aggregates, repositories, or bounded contexts. Clean Architecture + DDD + Hexagonal patterns for backend services, language-agnostic (Go, Rust, Python, TypeScript, Java, C#).
feature-slicing
Proactively apply when creating new features/components/pages or setting up frontend project structure. Triggers on FSD, feature slicing, frontend architecture, layer structure, module boundaries, scalable frontend, slice organization. Use when restructuring React/Next.js/Vue/Remix projects, organizing frontend code, fixing import violations, or migrating legacy codebases. Feature-Sliced Design (FSD) architecture for frontend projects.
slack-block-kit
Proactively apply when generating Slack API payloads with blocks, chat.postMessage calls with structured content, or views.open/views.publish calls. Triggers on Block Kit, Slack blocks, section block, actions block, header block, divider block, context block, table block, markdown block, rich text block, image block, input block, video block, context_actions block, plan block, task_card block, Slack modal, Slack App Home, Slack surfaces, Slack interactive elements, Slack button, Slack select menu, Slack overflow, Slack datepicker, Slack checkboxes, Slack radio buttons, Work Objects, Slack link unfurl, chat.postMessage blocks, views.open, views.update, views.push, views.publish, Slack composition objects. Use when building Block Kit payloads, constructing blocks arrays, creating modals or App Home views, adding interactive elements, implementing link unfurling with Work Objects, or designing rich message layouts. Slack Block Kit UI framework for building rich message layouts, modals, and App Home views.
mermaid-diagrams
Proactively suggest diagrams when explaining complex systems. Triggers on diagrams, charts, visualizations, flowcharts, sequence diagrams, architecture diagrams, ER diagrams, state machines, Gantt charts, mindmaps, C4, class diagrams, git graphs. Use when user asks for visual representations of code, systems, processes, data structures, database schemas, workflows, or API flows. Generate Mermaid diagrams in markdown.
modern-css
Proactively apply when creating design systems, component libraries, or any frontend application. Triggers on CSS Grid, Subgrid, Flexbox, Container Queries, :has(), @layer, @scope, CSS nesting, @property, @function, if(), oklch, color-mix, light-dark, relative color, @starting-style, scroll-driven animations, view transitions, anchor positioning, popover, customizable select, content-visibility, logical properties, text-wrap, interpolate-size, clamp, field-sizing, modern CSS, CSS architecture, responsive design, dark mode, theming, design tokens, cascade layers. Use when writing CSS for any web project, choosing layout approaches, building responsive components, implementing dark mode or theming, creating animations or transitions, styling form elements, or modernizing legacy stylesheets. Modern CSS features and best practices for building interfaces with pure native CSS.
Didn't find tool you were looking for?