Skip to content
Development
Skill

/drizzle-orm-d1

| Type-safe ORM for Cloudflare D1 databases using Drizzle. Use when: building D1 database schemas, writing type-safe SQL queries, managing migrations with Drizzle Kit, defining table relations, implementing prepared statements, using D1 batch API, or encountering D1_ERROR,

From plugin
secondsky-claude-skills
219183 skills42 agents62 commands2 MCP
Install
$ npx -y skills add secondsky/claude-skills --skill drizzle-orm-d1 --agent claude-code

How it fires

How this skill gets triggered: by you, by Claude, or both.

  • Fires itselfAuto-invocation. Claude auto-loads it when your prompt matches the work.Auto-invocation is when the right skill fires by itself at the right moment, driven by a FLOW.md router and a hook, instead of you invoking it by name. It is the difference between a skill being installed and a skill actually getting used.Read the full definition →
  • You can call itInvoke it directly when you want it.
  • Slash command/drizzle-orm-d1

Context preview

The summary Claude sees to decide when to auto-load this skill.

| Type-safe ORM for Cloudflare D1 databases using Drizzle. Use when: building D1 database schemas, writing type-safe SQL queries, managing migrations with Drizzle Kit, defining table relations, implementing prepared statements, using D1 batch API, or encountering D1_ERROR,

SKILL.md

drizzle-orm-d1.SKILL.md
name: drizzle-orm-d1
description: "| Type-safe ORM for Cloudflare D1 databases using Drizzle. Use when: building D1 database schemas, writing type-safe SQL queries, managing migrations with Drizzle Kit, defining table relations, implementing prepared statements, using D1 batch API, or encountering D1_ERROR, transaction errors, foreign key constraint failures, or schema inference issues."

metadata:
  keywords:
    - drizzle orm
    - drizzle d1
    - type-safe sql
    - drizzle schema
    - drizzle migrations
    - drizzle kit
    - orm cloudflare
    - d1 orm
    - drizzle typescript
    - drizzle relations
    - drizzle transactions
    - drizzle query builder
    - schema definition
    - prepared statements
    - drizzle batch
    - migration management
    - relational queries
    - drizzle joins
    - D1_ERROR
    - BEGIN TRANSACTION d1
    - foreign key constraint
    - migration failed
    - schema not found
    - d1 binding error
    - schema design
    - database indexes
    - soft deletes
    - uuid primary keys
    - enum constraints
    - performance optimization
    - naming conventions
    - schema testing

license: MIT

Drizzle ORM for Cloudflare D1

**Status**: Production Ready ✅ **Last Updated**: 2025-12-14 **Latest Version**: drizzle-orm@0.45.2, drizzle-kit@0.31.10 **Dependencies**: cloudflare-d1, cloudflare-worker-base

---

Quick Start (10 Minutes)

1. Install Drizzle

bun add drizzle-orm drizzle-kit

2. Configure Drizzle Kit

Create `drizzle.config.ts`:

import { defineConfig } from 'drizzle-kit';

export default defineConfig({
  schema: './src/db/schema.ts',
  out: './migrations',
  dialect: 'sqlite',          // MANDATORY since drizzle-kit 0.21 (D1 = sqlite)
  driver: 'd1-http',          // D1 HTTP driver for remote migrations/Studio
  dbCredentials: {            // MANDATORY: drizzle-kit 0.30+ tightened zod validation
    accountId: process.env.CLOUDFLARE_ACCOUNT_ID!,
    databaseId: process.env.CLOUDFLARE_DATABASE_ID!,
    token: process.env.CLOUDFLARE_D1_TOKEN!,
  },
});

> **drizzle-kit 0.30/0.31 note**: `dialect` and `dbCredentials` are now strictly > validated. A config that omits `dialect` or uses the old `connectionString`/ > `uri` keys will fail validation. For D1 use `dialect: 'sqlite'` + > `driver: 'd1-http'` with `accountId`/`databaseId`/`token` (or wrangler-based > credentials). The runtime `migrate()` signature in `drizzle-orm/<driver>/migrator` > is unchanged from 0.36 → 0.45 (it changes only in 1.0-beta, which is out of > scope for `^0.45`).

3. Define Schema

Create `src/db/schema.ts`:

import { sqliteTable, text, integer } from 'drizzle-orm/sqlite-core';
import { relations } from 'drizzle-orm';

export const users = sqliteTable('users', {
  id: integer('id').primaryKey({ autoIncrement: true }),
  email: text('email').notNull().unique(),
  name: text('name').notNull(),
  createdAt: integer('created_at', { mode: 'timestamp' }).$defaultFn(() => new Date()),
});

export const posts = sqliteTable('posts', {
  id: integer('id').primaryKey({ autoIncrement: true }),
  title: text('title').notNull(),
  content: text('content').notNull(),
  authorId: integer('author_id')
    .notNull()
    .references(() => users.id, { onDelete: 'cascade' }),
});

export const usersRelations = relations(users, ({ many }) => ({
  posts: many(posts),
}));

4. Generate & Apply Migrations

bunx drizzle-kit generate                           # Generate SQL
bunx wrangler d1 migrations apply my-database --local   # Apply local
bunx wrangler d1 migrations apply my-database --remote  # Apply prod

5. Query in Worker

import { drizzle } from 'drizzle-orm/d1';
import { users } from './db/schema';
import { eq } from 'drizzle-orm';

export default {
  async fetch(request: Request, env: { DB: D1Database }): Promise<Response> {
    const db = drizzle(env.DB);
    const allUsers = await db.select().from(users).all();
    return Response.json(allUsers);
  },
};

---

Critical Rules

Always Do

| Rule | Why | |------|-----| | Use `drizzle-kit generate` for migrations | Never write SQL manually | | Test migrations locally first | `--local` before `--remote` | | Use `.get()` for single results | Returns first row or undefined | | Use `db.batch()` for transactions | D1 doesn't support SQL BEGIN/COMMIT | | Use `integer` with `mode: 'timestamp'` for dates | D1 has no native date type | | Use `.$defaultFn()` for dynamic defaults | Not `.default()` for functions |

Never Do

| Rule | Why | |------|-----| | Use SQL `BEGIN TRANSACTION` | D1 requires batch API (Error #1) | | Mix `drizzle-kit migrate` and `wrangler apply` | Use Wrangler only | | Use `drizzle-kit push` for production | Use `generate` + `apply` | | Commit credentials in drizzle.config.ts | Use env vars | | Use `.default()` for function calls | Use `.$defaultFn()` instead |

---

Top 5 Critical Errors

| # | Error | Solution | |---|-------|----------| | 1 | `D1_ERROR: Cannot use BEGIN TRANSACTION` | Use `db.batch([...])` instead of `db.transaction()` | | 2 | `FOREIGN KEY constraint failed` | Define cascading: `.references(() => users.id, { onDelete: 'cascade' })` | | 3 | `env.DB is undefined` | Ensure binding in `wrangler.jsonc` matches `env.DB` | | 4 | `No such module "wrangler"` | Use `import { drizzle } from 'drizzle-orm/d1'` | | 5 | `Type instantiation excessively deep` | Use `InferSelectModel<typeof users>` for explicit types |

**See**: `references/error-catalog.md` for all 12 errors with complete solutions.

---

Common Patterns Summary

| Pattern | Use Case | Template | |---------|----------|----------| | **CRUD Operations** | Basic database operations | `templates/basic-queries.ts` | | **Relations & Joins** | Nested queries, manual joins | `templates/relations-queries.ts` | | **Batch Operations** | Transactions (D1 batch API) | `templates/transactions.ts` | | **Schema Design** | Naming, indexes, soft del

Read more
Ships withsecondsky-claude-skills

145 production-ready skills for Claude Code CLI 🔌 Platform / Harness Support These plugins ship as Claude Code marketplace plugins (.claude-plugin/ manifests) and Codex CLI plugins (.codex-plugin/ manifests).

Get the whole plugin

Other skills on secondsky-claude-skills.