From revskills
Drizzle ORM schema design, migrations, and query patterns for PostgreSQL. Use when creating tables, writing queries, defining relations, managing migrations, or working with NeonDB or Supabase. Covers pgTable, indexes, enums, jsonb columns, transactions, soft delete, pagination, drizzle-kit generate/migrate, and serverless connection patterns.
How this skill is triggered — by the user, by Claude, or both
Slash command
/revskills:drizzle-dbThis skill is limited to the following tools:
The summary Claude sees in its skill listing — used to decide when to auto-load this skill
```typescript
import { pgTable, text, timestamp, integer, boolean, jsonb, uuid, index } from 'drizzle-orm/pg-core';
export const users = pgTable('users', {
id: uuid('id').defaultRandom().primaryKey(),
email: text('email').notNull().unique(),
name: text('name').notNull(),
role: text('role', { enum: ['admin', 'user', 'guest'] }).notNull().default('user'),
metadata: jsonb('metadata').$type<UserMetadata>(),
createdAt: timestamp('created_at', { withTimezone: true }).notNull().defaultNow(),
updatedAt: timestamp('updated_at', { withTimezone: true }).notNull().defaultNow(),
}, (table) => [
index('users_email_idx').on(table.email),
]);
import { relations } from 'drizzle-orm';
export const usersRelations = relations(users, ({ many }) => ({
posts: many(posts),
}));
export const postsRelations = relations(posts, ({ one }) => ({
author: one(users, {
fields: [posts.authorId],
references: [users.id],
}),
}));
// Select with relations
const result = await db.query.users.findMany({
where: eq(users.role, 'admin'),
with: { posts: true },
limit: 10,
});
// Insert
const [newUser] = await db.insert(users)
.values({ email: '[email protected]', name: 'User' })
.returning();
// Update
await db.update(users)
.set({ name: 'Updated' })
.where(eq(users.id, userId));
// Delete
await db.delete(users).where(eq(users.id, userId));
// Transaction
await db.transaction(async (tx) => {
const [user] = await tx.insert(users).values(userData).returning();
await tx.insert(profiles).values({ userId: user.id });
});
# Generate migration from schema changes
drizzle-kit generate
# Apply migrations
drizzle-kit migrate
# Push schema directly (dev only)
drizzle-kit push
// drizzle.config.ts
import { defineConfig } from 'drizzle-kit';
export default defineConfig({
schema: './src/schema/*.ts',
out: './drizzle',
dialect: 'postgresql',
dbCredentials: {
url: process.env.DATABASE_URL!,
},
});
import { neon } from '@neondatabase/serverless';
import { drizzle } from 'drizzle-orm/neon-http';
const sql = neon(process.env.DATABASE_URL!);
const db = drizzle(sql, { schema });
neon-http driver for serverless (one-shot queries, no persistent connection)neon-serverless with WebSocket for transactionsexport const posts = pgTable('posts', {
// ...
deletedAt: timestamp('deleted_at', { withTimezone: true }),
});
// Always filter
const activePosts = await db.query.posts.findMany({
where: isNull(posts.deletedAt),
});
const page = await db.query.posts.findMany({
limit: 20,
offset: (pageNum - 1) * 20,
orderBy: [desc(posts.createdAt)],
});
interface UserPrefs {
theme: 'light' | 'dark';
notifications: boolean;
}
export const users = pgTable('users', {
prefs: jsonb('prefs').$type<UserPrefs>().default({ theme: 'light', notifications: true }),
});
.returning() on insert/update when you need the resultdrizzle-kit push in production — use migrations{ withTimezone: true }Skill by RevealUI Studio — the agentic business runtime.
npx claudepluginhub revealuistudio/revskills --plugin revskillsGuides creation, editing, and verification of skills for AI coding agents using test-driven development with subagent scenarios. Use when authoring or debugging skills.