
drizzle-orm-d1
Build type-safe D1 databases with Drizzle ORM. Includes schema definition, migrations with Drizzle Kit, relations, and D1 batch API patterns. Prevents 18 errors including SQL BEGIN failures, cascade data loss, 100-parameter limits, and foreign key issues. Use when: defining D1 schemas, managing migrations, bulk inserts, or troubleshooting D1ERROR, BEGIN TRANSACTION, foreign keys, "too many SQL variables".
- Installs
- 640
- Last 24h
- —
- Trending rank
- —
- Security
- Not audited
Install
Works with every agent the skills CLI supports.
npx skills add https://github.com/jezweb/claude-skills --skill drizzle-orm-d1- 01
Install
Run the command in your project. The CLI asks which agents to install for.
- 02
Describe the task
Ask your agent for something this skill covers. It loads drizzle-orm-d1 automatically when relevant.
- 03
Review the result
The agent follows the SKILL.md steps, scripts and references bundled with the skill.
SKILL.md
The instructions your agent reads when the skill is triggered.
Drizzle ORM for Cloudflare D1
Status: Production Ready ✅ Last Updated: 2026-02-03
Commands
| Command | Purpose |
|---|---|
/db-init | Set up Drizzle ORM with D1 (schema, config, migrations) |
/migrate | Generate and apply database migrations |
/seed | Seed database with initial or test data |
| Latest Version: drizzle-orm@0.45.1, drizzle-kit@0.31.8, better-sqlite3@12.5.0 | |
| Dependencies: cloudflare-d1, cloudflare-worker-base |
Quick Start (5 Minutes)
# 1. Install
npm install drizzle-orm
npm install -D drizzle-kit
# 2. Configure drizzle.config.ts
import { defineConfig } from 'drizzle-kit';
export default defineConfig({
schema: './src/db/schema.ts',
out: './migrations',
dialect: 'sqlite',
driver: 'd1-http',
dbCredentials: {
accountId: process.env.CLOUDFLARE_ACCOUNT_ID!,
databaseId: process.env.CLOUDFLARE_DATABASE_ID!,
token: process.env.CLOUDFLARE_D1_TOKEN!,
},
});
# 3. Configure wrangler.jsonc
{
"d1_databases": [{
"binding": "DB",
"database_name": "my-database",
"database_id": "your-database-id",
"migrations_dir": "./migrations" // CRITICAL: Points to Drizzle migrations
}]
}
# 4. Define schema (src/db/schema.ts)
import { sqliteTable, text, integer } from 'drizzle-orm/sqlite-core';
export const users = sqliteTable('users', {
id: integer('id').primaryKey({ autoIncrement: true }),
email: text('email').notNull().unique(),
createdAt: integer('created_at', { mode: 'timestamp' }).$defaultFn(() => new Date()),
});
# 5. Generate & apply migrations
npx drizzle-kit generate
npx wrangler d1 migrations apply my-database --local # Test first
npx wrangler d1 migrations apply my-database --remote # Then production
# 6. Query in Worker
import { drizzle } from 'drizzle-orm/d1';
import { users } from './db/schema';
const db = drizzle(env.DB);
const allUsers = await db.select().from(users).all();
D1-Specific Critical Rules
✅ Use db.batch() for transactions - D1 doesn't support SQL BEGIN/COMMIT (see Issue #1)
✅ Test migrations locally first - Always --local before --remote
✅ Use integer with mode: 'timestamp' for dates - D1 has no native date type
✅ Use .$defaultFn() for dynamic defaults - Not .default() for functions
✅ Set migrations_dir in wrangler.jsonc - Points to ./migrations
❌ Never use SQL BEGIN TRANSACTION - D1 requires batch API
❌ Never use drizzle-kit push for production - Use generate + apply
❌ Never mix wrangler.toml and wrangler.jsonc - Use wrangler.jsonc only
Drizzle Kit Tools
Drizzle Studio (Visual Database Browser)
npx drizzle-kit studio
# Opens http://local.drizzle.studio
# For remote D1 database
npx drizzle-kit studio --port 3001
Features:
- Browse tables and data visually
- Edit records inline
- Run custom SQL queries
- View schema relationships
Migration Commands
| Command | Purpose |
|---|---|
drizzle-kit generate | Generate SQL migrations from schema changes |
drizzle-kit push | Push schema directly (dev only, not for production) |
drizzle-kit pull | Introspect existing database → Drizzle schema |
drizzle-kit check | Validate migration integrity (race conditions) |
drizzle-kit up | Upgrade migration snapshots to latest format |
# Introspect existing D1 database
npx drizzle-kit pull
# Validate migrations haven't collided
npx drizzle-kit check
Advanced Query Patterns
Dynamic Query Building
Build queries conditionally with .$dynamic():
import { eq, and, or, like, sql } from 'drizzle-orm';
// Base query
function getUsers(filters: { name?: string; email?: string; active?: boolean }) {
let query = db.select().from(users).$dynamic();
if (filters.name) {
query = query.where(like(users.name, `%${filters.name}%`));
}
if (filters.email) {
query = query.where(eq(users.email, filters.email));
}
if (filters.active !== undefined) {
query = query.where(eq(users.active, filters.active));
}
return query;
}
// Usage
const results = await getUsers({ name: 'John', active: true });
Upsert (Insert or Update on Conflict)
import { users } from './schema';
// Insert or ignore if exists
await db.insert(users)
.values({ id: 1, email: 'test@example.com', name: 'Test' })
.onConflictDoNothing();
// Insert or update specific fields on conflict
await db.insert(users)
.values({ id: 1, email: 'test@example.com', name: 'Test' })
.onConflictDoUpdate({
target: users.email, // Conflict on unique email
set: {
name: sql`excluded.name`, // Use value from INSERT
updatedAt: new Date(),
},
});
⚠️ D1 Upsert Caveat: Target must be a unique column or primary key.
Debugging with Logging
import { drizzle } from 'drizzle-orm/d1';
// Enable query logging
const db = drizzle(env.DB, { logger: true });
// Custom logger
const db = drizzle(env.DB, {
logger: {
logQuery(query, params) {
console.log('SQL:', query);
console.log('Params:', params);
},
},
});
// Get SQL without executing (for debugging)
const query = db.select().from(users).where(eq(users.id, 1));
const sql = query.toSQL();
console.log(sql.sql, sql.params);
Known Issues Prevention
This skill prevents 18 documented issues:
Issue #1: D1 Transaction Errors
Error: D1_ERROR: Cannot use BEGIN TRANSACTION
Source: https://github.com/drizzle-team/drizzle-orm/issues/4212
Why: Drizzle uses SQL BEGIN TRANSACTION, but D1 requires batch API instead.
Prevention: Use db.batch([...]) instead of db.transaction()
Issue #2: Foreign Key Constraint Failures
Error: FOREIGN KEY constraint failed: SQLITE_CONSTRAINT
Source: https://github.com/drizzle-team/drizzle-orm/issues/4089
Why: Drizzle uses PRAGMA foreign_keys = OFF; which causes migration failures.
Prevention: Define foreign keys with cascading: .references(() => users.id, { onDelete: 'cascade' })
Issue #3: Module Import Errors in Production
Error: Error: No such module "wrangler"
Source: https://github.com/drizzle-team/drizzle-orm/issues/4257
Why: Importing from wrangler package in runtime code fails in production.
Prevention: Use import { drizzle } from 'drizzle-orm/d1', never import from wrangler
Issue #4: D1 Binding Not Found
Error: TypeError: Cannot read property 'prepare' of undefined
Why: Binding name in code doesn't match wrangler.jsonc configuration.
Prevention: Ensure "binding": "DB" in wrangler.jsonc matches env.DB in code
Issue #5: Migration Apply Failures
Error: Migration failed to apply: near "...": syntax error
Why: Syntax errors or applying migrations out of order.
Prevention: Test locally first (--local), review generated SQL, regenerate if needed
Issue #6: Schema TypeScript Inference Errors
Error: Type instantiation is excessively deep and possibly infinite
Why: Complex circular references in relations.
Prevention: Use explicit types with InferSelectModel<typeof users>
Issue #7: Prepared Statement Caching Issues
Error: Stale or incorrect query results
Why: D1 doesn't cache prepared statements like traditional SQLite.
Prevention: Always use .all() or .get() methods, don't reuse statements across requests
Issue #8: Transaction Rollback Patterns
Error: Transaction doesn't roll back on error Why: D1 batch API doesn't support traditional rollback. Prevention: Implement error handling with manual cleanup in try/catch
Issue #9: TypeScript Strict Mode Errors
Error: Type errors with strict: true
Why: Drizzle types can be loose.
Prevention: Use explicit return types: Promise<User | undefined>
Issue #10: Drizzle Config Not Found
Error: Cannot find drizzle.config.ts
Why: Wrong file location or name.
Prevention: File must be drizzle.config.ts in project root
Issue #11: Remote vs Local D1 Confusion
Error: Changes not appearing in dev or production
Why: Applying migrations to wrong database.
Prevention: Use --local for dev, --remote for production
Issue #12: wrangler.toml vs wrangler.jsonc
Error: Configuration not recognized
Why: Mixing TOML and JSON formats.
Prevention: Use wrangler.jsonc consistently (supports comments)
Issue #13: D1 100-Parameter Limit in Bulk Inserts
Error: too many SQL variables at offset
Source: drizzle-orm#2479, Cloudflare D1 Limits
Why It Happens: Cloudflare D1 has a hard limit of 100 bound parameters per query. When inserting multiple rows, Drizzle doesn't automatically chunk. If (rows × columns) > 100, the query fails.
Prevention: Use manual chunking or autochunk pattern
Example - When It Fails:
// 35 rows × 3 columns = 105 parameters → FAILS
const books = Array(35).fill({}).map((_, i) => ({
id: i.toString(),
title: "Book",
author: "Author",
}));
await db.insert(schema.books).values(books);
// Error: too many SQL variables at offset
Solution - Manual Chunking:
async function batchInsert<T>(
db: any,
table: any,
items: T[],
chunkSize = 32
) {
for (let i = 0; i < items.length; i += chunkSize) {
await db.insert(table).values(items.slice(i, i + chunkSize));
}
}
await batchInsert(db, schema.books, books);
Solution - Auto-Chunk by Column Count:
const D1_MAX_PARAMETERS = 100;
async function autochunk<T extends Record<string, unknown>, U>(
{ items, otherParametersCount = 0 }: {
items: T[];
otherParametersCount?: number;
},
cb: (chunk: T[]) => Promise<U>,
) {
const chunks: T[][] = [];
let chunk: T[] = [];
let chunkParameters = 0;
for (const item of items) {
const itemParameters = Object.keys(item).length;
if (chunkParameters + itemParameters + otherParametersCount > D1_MAX_PARAMETERS) {
chunks.push(chunk);
chunkParameters = itemParameters;
chunk = [item];
continue;
}
chunk.push(item);
chunkParameters += itemParameters;
}
if (chunk.length) chunks.push(chunk);
const results: U[] = [];
for (const c of chunks) {
results.push(await cb(c));
}
return results.flat();
}
// Usage
const inserted = await autochunk(
{ items: books },
(chunk) => db.insert(schema.books).values(chunk).returning()
);
Note: This also affects drizzle-seed. Use seed(db, schema, { count: 10 }) to limit seed size.
Issue #14: findFirst with Batch API Returns Error Instead of Undefined
Error: TypeError: Cannot read properties of undefined (reading '0')
Source: drizzle-orm#2721
Why It Happens: When using findFirst in a batch operation with D1, if no results are found, Drizzle throws a TypeError instead of returning null or undefined. This breaks error handling patterns that expect falsy return values.
Prevention: Use pnpm patch to fix the D1 session handler, or avoid findFirst in batch operations
Example - When It Fails:
// Works fine - returns null/undefined when not found
const result = await db.query.table.findFirst({
where: eq(schema.table.key, 'not-existing'),
});
// Throws TypeError instead of returning undefined
const [result] = await db.batch([
db.query.table.findFirst({
where: eq(schema.table.key, 'not-existing'),
}),
]);
// Error: TypeError: Cannot read properties of undefined (reading '0')
Solution - Patch drizzle-orm:
# Create patch with pnpm
pnpm patch drizzle-orm
Then edit node_modules/drizzle-orm/d1/session.js:
// In mapGetResult method, add null check:
if (!result) {
return undefined;
}
if (this.customResultMapper) {
return this.customResultMapper([result]);
}
Workaround - Avoid findFirst in Batch:
// Instead of batch with findFirst, use separate queries
const result = await db.query.table.findFirst({
where: eq(schema.table.key, key),
});
Issue #15: D1 Generated Columns Not Supported
Error: No schema API for generated columns Source: drizzle-orm#4538, D1 Generated Columns Why It Happens: Cloudflare D1 supports generated columns for extracting/calculating values from JSON or other columns, which can dramatically improve query performance when indexed. Drizzle ORM doesn't have a schema API to define these columns, forcing users to write raw SQL. Prevention: Use raw SQL migrations for generated columns
Example - D1 Supports This:
-- D1 supports this, but Drizzle has no JS equivalent
CREATE TABLE products (
id INTEGER PRIMARY KEY,
data TEXT,
price REAL GENERATED ALWAYS AS (json_extract(data, '$.price')) STORED
);
CREATE INDEX idx_price ON products(price);
Workaround - Use Raw SQL:
import { sql } from 'drizzle-orm';
// Current workaround - raw SQL only
await db.run(sql`
CREATE TABLE products (
id INTEGER PRIMARY KEY,
data TEXT,
price REAL GENERATED ALWAYS AS (json_extract(data, '$.price')) STORED
)
`);
// Or in migration file (migrations/XXXX_add_generated.sql)
CREATE INDEX idx_price ON products(price);
Note: This is a known limitation, not a bug. Feature requested but not yet implemented.
Issue #16: Migration Generator Silently Causes CASCADE DELETE Data Loss
Error: Related data silently deleted during migrations
Source: drizzle-orm#4938
Why It Happens: Drizzle generates PRAGMA foreign_keys=OFF before table recreation, but Cloudflare D1 ignores this pragma. CASCADE DELETE still triggers, destroying all related data.
Prevention: Manually rewrite dangerous migrations with backup/restore pattern
⚠️ CRITICAL WARNING: This can cause permanent data loss in production.
When It Happens:
Any schema change that requires table recreation (adding/removing columns, changing types) will DROP and recreate the table. If foreign keys reference this table with onDelete: "cascade", ALL related data is deleted.
Example - Dangerous Migration:
// Schema with cascade relationships
export const account = sqliteTable("account", {
accountId: integer("account_id").primaryKey(),
name: text("name"),
});
export const property = sqliteTable("property", {
propertyId: integer("property_id").primaryKey(),
accountId: integer("account_id").references(() => account.accountId, {
onDelete: "cascade" // ⚠️ CASCADE DELETE
}),
});
// Change account schema (e.g., add a column)
// npx drizzle-kit generate creates:
// DROP TABLE account; -- ⚠️ Silently destroys ALL properties via cascade!
// CREATE TABLE account (...);
Safe Migration Pattern:
-- Manually rewrite migration to backup related data
PRAGMA foreign_keys=OFF; -- D1 ignores this, but include anyway
-- 1. Backup related tables
CREATE TABLE backup_property AS SELECT * FROM property;
-- 2. Drop and recreate parent table
DROP TABLE account;
CREATE TABLE account (
account_id INTEGER PRIMARY KEY,
name TEXT,
-- new columns here
);
-- 3. Restore related data
INSERT INTO property SELECT * FROM backup_property;
DROP TABLE backup_property;
PRAGMA foreign_keys=ON;
Detection: Always review generated migrations before applying. Look for:
DROP TABLEstatements for tables with foreign key references- Tables with
onDelete: "cascade"relationships
Workarounds:
- Option 1: Manually rewrite migrations (safest)
- Option 2: Use
onDelete: "set null"instead of"cascade"for schema changes - Option 3: Temporarily remove foreign keys during migration
Reproduction: https://github.com/ZerGo0/drizzle-d1-reprod
Impact: Affects better-auth migration from v1.3.7+, any D1 schema with foreign keys.
Issue #17: sql Template in D1 Batch Causes TypeError
Error: TypeError: Cannot read properties of undefined (reading 'bind')
Source: drizzle-orm#2277
Why It Happens: Using sql template literals inside db.batch() causes TypeError. The same SQL works fine outside of batch operations.
Prevention: Use query builder instead of sql template in batch operations
Example - When It Fails:
const upsertSql = sql`insert into ${schema.subscriptions}
(id, status) values (${id}, ${status})
on conflict (id) do update set status = ${status}
returning *`;
// Works fine
const [subscription] = await db.all<Subscription>(upsertSql);
// Throws TypeError: Cannot read properties of undefined (reading 'bind')
const [[batchSubscription]] = await db.batch([
db.all<Subscription>(upsertSql),
]);
Solution - Use Query Builder:
// Use Drizzle query builder instead
const [result] = await db.batch([
db.insert(schema.subscriptions)
.values({ id, status })
.onConflictDoUpdate({
target: schema.subscriptions.id,
set: { status }
})
.returning()
]);
Workaround - Convert to Native D1:
import { SQLiteSyncDialect } from 'drizzle-orm/sqlite-core';
const sqliteDialect = new SQLiteSyncDialect();
const upsertQuery = sqliteDialect.sqlToQuery(upsertSql);
const [result] = await D1.batch([
D1.prepare(upsertQuery.sql).bind(...upsertQuery.params),
]);
Issue #18: Drizzle 1.0 Nested Migrations Not Found by Wrangler
Error: Migrations silently fail to apply (no error message)
Source: drizzle-orm#5266
Why It Happens: Drizzle 1.0 beta generates nested migration folders, but wrangler d1 migrations apply only looks for files directly in the configured directory.
Prevention: Flatten migrations with post-generation script
Migration Structure Issue:
# Drizzle 1.0 beta generates this:
migrations/
20260116123456_random/
migration.sql
20260117234567_another/
migration.sql
# But wrangler expects this:
migrations/
20260116123456_random.sql
20260117234567_another.sql
Detection:
npx wrangler d1 migrations apply my-db --remote
# Output: "No migrations found" (even though migrations exist)
Solution - Post-Generation Script:
// scripts/flatten-migrations.ts
import fs from 'fs/promises';
import path from 'path';
const migrationsDir = './migrations';
async function flattenMigrations() {
const entries = await fs.readdir(migrationsDir, { withFileTypes: true });
for (const entry of entries) {
if (entry.isDirectory()) {
const sqlFile = path.join(migrationsDir, entry.name, 'migration.sql');
const flatFile = path.join(migrationsDir, `${entry.name}.sql`);
// Move migration.sql out of folder
await fs.rename(sqlFile, flatFile);
// Remove empty folder
await fs.rmdir(path.join(migrationsDir, entry.name));
console.log(`Flattened: ${entry.name}/migration.sql → ${entry.name}.sql`);
}
}
}
flattenMigrations().catch(console.error);
package.json Integration:
{
"scripts": {
"db:generate": "drizzle-kit generate",
"db:flatten": "tsx scripts/flatten-migrations.ts",
"db:migrate": "npm run db:generate && npm run db:flatten && wrangler d1 migrations apply my-db"
}
}
Workaround Until Fixed: Always run the flatten script after generating migrations:
npx drizzle-kit generate
tsx scripts/flatten-migrations.ts
npx wrangler d1 migrations apply my-db --remote
Status: Feature request to add flat: true config option (not yet implemented).
Batch API Pattern (D1 Transactions)
// ❌ DON'T: Use traditional transactions (fails with D1_ERROR)
await db.transaction(async (tx) => { /* ... */ });
// ✅ DO: Use D1 batch API
const results = await db.batch([
db.insert(users).values({ email: 'test@example.com', name: 'Test' }),
db.insert(posts).values({ title: 'Post', content: 'Content', authorId: 1 }),
]);
// With error handling
try {
await db.batch([...]);
} catch (error) {
console.error('Batch failed:', error);
// Manual cleanup if needed
}
Using Bundled Resources
Scripts (scripts/)
check-versions.sh - Verify package versions are up to date
./scripts/check-versions.sh
Output:
Checking Drizzle ORM versions...
✓ drizzle-orm: 0.44.7 (latest)
✓ drizzle-kit: 0.31.5 (latest)
References (references/)
Claude should load these when you need specific deep-dive information:
- wrangler-setup.md - Complete Wrangler configuration guide (local vs remote, env vars)
- schema-patterns.md - All D1/SQLite column types, constraints, indexes
- migration-workflow.md - Complete migration workflow (generate, test, apply)
- query-builder-api.md - Full Drizzle query builder API reference
- common-errors.md - All 18 errors with detailed solutions
- links-to-official-docs.md - Organized links to official documentation
When to load:
- User asks about specific column types → load schema-patterns.md
- User encounters migration errors → load migration-workflow.md + common-errors.md
- User needs complete API reference → load query-builder-api.md
Dependencies
Required:
drizzle-orm@0.45.1- ORM runtimedrizzle-kit@0.31.8- CLI tool for migrations
Optional:
better-sqlite3@12.4.6- For local SQLite development@cloudflare/workers-types@4.20251125.0- TypeScript types
Skills:
- cloudflare-d1 - D1 database creation and raw SQL queries
- cloudflare-worker-base - Worker project structure and Hono setup
Official Documentation
- Drizzle ORM: https://orm.drizzle.team/
- Drizzle with D1: https://orm.drizzle.team/docs/connect-cloudflare-d1
- Drizzle Kit: https://orm.drizzle.team/docs/kit-overview
- Drizzle Migrations: https://orm.drizzle.team/docs/migrations
- GitHub: https://github.com/drizzle-team/drizzle-orm
- Cloudflare D1: https://developers.cloudflare.com/d1/
- Wrangler D1 Commands: https://developers.cloudflare.com/workers/wrangler/commands/#d1
- Context7 Library:
/drizzle-team/drizzle-orm-docs
Package Versions (Verified 2026-01-06)
{
"dependencies": {
"drizzle-orm": "^0.45.1"
},
"devDependencies": {
"drizzle-kit": "^0.31.8",
"@cloudflare/workers-types": "^4.20260103.0",
"better-sqlite3": "^12.5.0"
}
}
Production Example
This skill is based on production patterns from:
- Cloudflare Workers + D1: Serverless edge databases
- Drizzle ORM: Type-safe ORM used in production apps
- Errors: 0 (all 18 known issues prevented)
- Validation: ✅ Complete blog example (users, posts, comments)
Last verified: 2026-01-20 | Skill version: 3.1.0 | Changes: Added 6 critical findings (100-parameter limit, cascade data loss, nested migrations, batch API edge cases, generated columns limitation)
Token Savings: ~60% compared to manual setup Error Prevention: 100% (all 18 known issues documented and prevented) Ready for production! ✅
FAQ
What does the drizzle-orm-d1 skill do?
Build type-safe D1 databases with Drizzle ORM. Includes schema definition, migrations with Drizzle Kit, relations, and D1 batch API patterns. Prevents 18 errors including SQL BEGIN failures, cascade data loss, 100-parameter limits, and foreign key issues. Use when: defining D1 schemas, managing migrations, bulk inserts, or troubleshooting D1ERROR, BEGIN TRANSACTION, foreign keys, "too many SQL variables".
How do I install drizzle-orm-d1?
Run npx skills add https://github.com/jezweb/claude-skills --skill drizzle-orm-d1 in your project. The skills CLI detects the agents you use and copies the skill into the right folder. For Claude Code you can also place the skill folder at ~/.claude/skills/drizzle-orm-d1/ (personal) or .claude/skills/drizzle-orm-d1/ (project).
Which AI agents can use drizzle-orm-d1?
Any agent that supports the open Agent Skills format (a folder with a SKILL.md file), including Claude Code, Codex, Cursor, GitHub Copilot, Gemini CLI, Windsurf, Cline, OpenCode and more.
Is drizzle-orm-d1 safe to install?
No partner security audit is available yet. Skills can run commands and scripts, so read the SKILL.md and any bundled files before installing.
Who maintains drizzle-orm-d1?
It is published by jezweb in jezweb/claude-skills. It has 640 recorded installs.
More from jezweb/claude-skills
shadcn-ui
jezweb/claude-skills
Install and configure shadcn/ui components for React projects. Guides component selection, installation order, dependency management, customisation with semantic tokens, and common UI recipes (forms, data tables, navigation, modals). Use after tailwind-theme-builder has set up the theme infrastructure, when adding components, building forms, creating data tables, or setting up navigation.
color-palette
jezweb/claude-skills
Generate complete, accessible colour palettes from a single brand hex. Produces 11-shade scale (50-950), semantic tokens, dark mode variants, Tailwind v4 CSS output, WCAG contrast checks. Use whenever the user supplies a brand hex and asks for a palette, mentions setting up a design system, wants Tailwind theme colours from a brand colour, or asks to check colour accessibility / contrast.
tailwind-theme-builder
jezweb/claude-skills
Set up Tailwind v4 + shadcn/ui themed UI with dark mode. Install deps, configure CSS variables via @theme inline, wire dark mode toggle, verify. Use whenever the user mentions Tailwind v4, setting up Tailwind theming, shadcn/ui colours, dark mode, or troubleshooting colours not working, tw-animate-css errors, @theme inline conflicts, @apply breaking after upgrade, or v3 → v4 migration issues.
wordpress-elementor
jezweb/claude-skills
Edit Elementor pages and manage templates on WordPress sites via browser automation (for visual / structural changes) or WP-CLI (for safe text replacements). Use whenever the user wants to edit an Elementor page, update text in Elementor widgets, apply or manage Elementor templates, or make content changes to pages built with the Elementor page builder.
ux-audit
jezweb/claude-skills
Walk through a live web app AS a real user to find usability + behavioural bugs that static reviews miss. REQUIRES proof of interaction (typing, clicking, sending, observing) before any verdict — a sweep that didn't interact terminates with verdict 'Incomplete'. Walks threads, exercises every element, runs the multi-pane stress matrix, visual polish sweep, component perfection checklist, automated a11y (axe-core), pragmatic performance budget (LCP/CLS/INP), scenario battery (11 scenarios), and stress recipes including the real-flavour data battery. Hard gates: console errors/warnings = 0, network 5xx = 0, layout collapse = 0, axe Critical/Serious = 0, perf budget green. Audit-the-audit meta-check rejects rushed reports. Each finding has reproduction steps, evidence path, and suspected code location. Trigger with 'ux audit', 'walkthrough', 'qa sweep', 'audit the app', 'dogfood this', 'check all pages', 'find what's broken', 'stress the UI'.
tailwind-v4-shadcn
jezweb/claude-skills
Set up Tailwind v4 with shadcn/ui using @theme inline pattern and CSS variable architecture. Four-step pattern: CSS variables, Tailwind mapping, base styles, automatic dark mode. Prevents 8 documented errors. Use when initializing React projects with Tailwind v4, or fixing colors not working, tw-animate-css errors, @theme inline dark mode conflicts, @apply breaking, v3 migration issues.
Popular data & databases skills
supabase-postgres-best-practices
supabase/agent-skills
Postgres best practices maintained by Supabase, for Postgres running anywhere. Load this skill BEFORE writing or changing anything that lives in a Postgres database: creating or altering tables and columns (including choosing column types), schema design, migrations and declarative schema files, RLS policies and the tests that verify them, indexes, triggers, database functions, queues and scheduled jobs (pgcron, pgmq), vector/semantic search (pgvector), and restoring dumps (pgrestore) or importing data. Also load it when diagnosing slow queries, high CPU, timeouts, EXPLAIN plans, connection exhaustion, locking, bloat, or rows visible to the wrong user or tenant. This is not just a performance guide — schema, migration, security, and SQL authoring tasks need these rules too, even for a one-column change or a single query.
prisma-client-api
prisma/skills
Prisma Client API reference covering model queries, filters, operators, and client methods. Use when writing database queries, using CRUD operations, filtering data, or configuring Prisma Client. Triggers on "prisma query", "findMany", "create", "update", "delete", "$transaction".
prisma-database-setup
prisma/skills
Deprecated compatibility name for prisma-orm-setup. Use only when a user or existing integration explicitly invokes prisma-database-setup; otherwise select prisma-orm-setup.
prisma-cli
prisma/skills
Prisma ORM 7 CLI reference for existing Prisma 7 applications or explicitly selected Prisma 7 workflows. Covers prisma init, generate, migrate, db, dev, studio, and mcp. For setup, connection repair, or Prisma 8, use prisma-orm-setup; not the Prisma Platform CLI.
prisma-postgres
prisma/skills
Deprecated compatibility name for prisma-postgres-setup. Use only when a user or existing integration explicitly invokes prisma-postgres; otherwise select prisma-postgres-setup.
prisma-driver-adapter-implementation
prisma/skills
Required reference for Prisma ORM 7 SQL driver adapter work. Use when implementing or modifying adapters, adding database drivers, or touching SqlDriverAdapter, Transaction, savepoint, result mapping, or DriverAdapterError behavior. Covers current transaction lifecycle, optional savepoint hooks, original database-error preservation, and verification.