agentleFS
revealui-studiorevealui-studio/revskills/skills/drizzle-db/SKILL.md

drizzle-db

Skill2 starsChanged 40 days agoMITView on GitHub

Drizzle ORM schema design, migrations, and query patterns for PostgreSQL. Use when creating tables, writing queries, defining relations, managing migrations, or working with NeonDB. Covers pgTable, indexes, enums, jsonb columns, transactions, soft delete, pagination, drizzle-kit generate/migrate, and serverless connection patterns.

  • Reads credentials

We split this skill into the rules it gives an agent

8 rules. About 0 are common, 3 are distinctive, and 5 are very specific to this project.

  • ≈0

    Common · estimate

    Many files like this have a rule of this kind.

  • ≈3

    Distinctive · estimate

    This author's own choices. Worth a look.

  • 5

    Very specific

    Tied to their project's names, files or tools. Probably skip.

  • Common
  • Distinctive
  • Very specific
  1. Very specific:

    Use neon-http driver for serverless (one-shot queries, no persistent connection)

    line 116
  2. Very specific:

    Use neon-serverless with WebSocket for transactions

    line 117
  3. Distinctive:

    Don't use raw SQL when Drizzle query builder works

    line 158
  4. Very specific:

    Don't skip .returning() on insert/update when you need the result

    line 159
  5. Distinctive:

    Don't forget indexes on columns used in WHERE clauses

    line 160
  6. Very specific:

    Don't use drizzle-kit push in production — use migrations

    line 161
  7. Very specific:

    Don't store dates without timezone — always use { withTimezone: true }

    line 162
  8. Distinctive:

    Don't forget to close connections in serverless (use connection pooling)

    line 163

≈ “Common” is an estimate: at least 1 in 5 of the 308,232 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.

Keep what fits and drop the rest. Your version, ready for your agents.
Files
SKILL.md

Drizzle ORM Patterns

Schema Definition

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),
]);

Relations

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],
  }),
}));

Queries

// 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: 'user@example.com', 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 });
});

Migrations

# 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!,
  },
});

NeonDB (Serverless)

import { neon } from '@neondatabase/serverless';
import { drizzle } from 'drizzle-orm/neon-http';

const sql = neon(process.env.DATABASE_URL!);
const db = drizzle(sql, { schema });
  • Use neon-http driver for serverless (one-shot queries, no persistent connection)
  • Use neon-serverless with WebSocket for transactions
  • Branch databases for dev/test/staging

Common Patterns

Soft Delete

export const posts = pgTable('posts', {
  // ...
  deletedAt: timestamp('deleted_at', { withTimezone: true }),
});

// Always filter
const activePosts = await db.query.posts.findMany({
  where: isNull(posts.deletedAt),
});

Pagination

const page = await db.query.posts.findMany({
  limit: 20,
  offset: (pageNum - 1) * 20,
  orderBy: [desc(posts.createdAt)],
});

Type-Safe JSON

interface UserPrefs {
  theme: 'light' | 'dark';
  notifications: boolean;
}

export const users = pgTable('users', {
  prefs: jsonb('prefs').$type<UserPrefs>().default({ theme: 'light', notifications: true }),
});

Common Mistakes to Avoid

  1. Don't use raw SQL when Drizzle query builder works
  2. Don't skip .returning() on insert/update when you need the result
  3. Don't forget indexes on columns used in WHERE clauses
  4. Don't use drizzle-kit push in production — use migrations
  5. Don't store dates without timezone — always use { withTimezone: true }
  6. Don't forget to close connections in serverless (use connection pooling)

Skill by RevealUI Studio — the agentic business runtime.

Download now (ZIP)

Does it work?

Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.

Reviews can't be read right now.

Your trail

Files you open will collect here, so you can find them again.

Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.

Now do this for your own.

Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.