/cloudflare-d1
Cloudflare D1 SQLite database with Workers, Drizzle ORM, migrations
$ npx -y skills add alinaqi/maggy --skill cloudflare-d1 --agent claude-codeHow 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
/cloudflare-d1
Context preview
The summary Claude sees to decide when to auto-load this skill.
Cloudflare D1 SQLite database with Workers, Drizzle ORM, migrations
SKILL.md
cloudflare-d1.SKILL.mdname: cloudflare-d1
description: Cloudflare D1 SQLite database with Workers, Drizzle ORM, migrations
when-to-use: When working with Cloudflare D1 or Workers
user-invocable: false
paths: ["wrangler.toml", "src/worker*", "**/d1/**"]
effort: medium
Cloudflare D1 Skill
Cloudflare D1 is a serverless SQLite database designed for Cloudflare Workers with global distribution and zero cold starts.
**Sources:** [D1 Docs](https://developers.cloudflare.com/d1/) | [Drizzle + D1](https://orm.drizzle.team/docs/connect-cloudflare-d1) | [Wrangler CLI](https://developers.cloudflare.com/workers/wrangler/)
---
Core Principle
**SQLite at the edge, migrations in version control, Drizzle for type safety.**
D1 brings SQLite's simplicity to serverless. Design for horizontal scale (multiple small databases) rather than vertical (one large database). Use Drizzle ORM for type-safe queries and migrations.
---
D1 Stack
| Component | Purpose | |-----------|---------| | **D1** | Serverless SQLite database | | **Workers** | Edge runtime for your application | | **Wrangler** | CLI for development and deployment | | **Drizzle ORM** | Type-safe ORM with migrations | | **Drizzle Kit** | Migration tooling | | **Hono** | Lightweight web framework (optional) |
---
Project Setup
Create Worker Project
# Create new project
npm create cloudflare@latest my-app -- --template "worker-typescript"
cd my-app
# Install dependencies
npm install drizzle-orm
npm install -D drizzle-kit
Create D1 Database
# Create database (creates both local and remote)
npx wrangler d1 create my-database
# Output:
# [[d1_databases]]
# binding = "DB"
# database_name = "my-database"
# database_id = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
Configure wrangler.toml
name = "my-app"
main = "src/index.ts"
compatibility_date = "2024-01-01"
[[d1_databases]]
binding = "DB"
database_name = "my-database"
database_id = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
migrations_dir = "drizzle"
migrations_table = "drizzle_migrations"
Generate TypeScript Types
# Generate env types from wrangler.toml
npx wrangler types
# Creates worker-configuration.d.ts:
# interface Env {
# DB: D1Database;
# }---
Drizzle ORM Setup
Schema Definition
// src/db/schema.ts
import { sqliteTable, text, integer, real, blob } from 'drizzle-orm/sqlite-core';
import { sql } from 'drizzle-orm';
export const users = sqliteTable('users', {
id: integer('id').primaryKey({ autoIncrement: true }),
email: text('email').notNull().unique(),
name: text('name').notNull(),
role: text('role', { enum: ['user', 'admin'] }).default('user'),
createdAt: text('created_at').default(sql`CURRENT_TIMESTAMP`),
updatedAt: text('updated_at').default(sql`CURRENT_TIMESTAMP`)
});
export const posts = sqliteTable('posts', {
id: integer('id').primaryKey({ autoIncrement: true }),
title: text('title').notNull(),
content: text('content'),
authorId: integer('author_id').references(() => users.id),
published: integer('published', { mode: 'boolean' }).default(false),
viewCount: integer('view_count').default(0),
createdAt: text('created_at').default(sql`CURRENT_TIMESTAMP`)
});
export const tags = sqliteTable('tags', {
id: integer('id').primaryKey({ autoIncrement: true }),
name: text('name').notNull().unique()
});
export const postTags = sqliteTable('post_tags', {
postId: integer('post_id').references(() => posts.id),
tagId: integer('tag_id').references(() => tags.id)
});
// Type exports
export type User = typeof users.$inferSelect;
export type NewUser = typeof users.$inferInsert;
export type Post = typeof posts.$inferSelect;
export type NewPost = typeof posts.$inferInsert;Drizzle Config
// drizzle.config.ts
import { defineConfig } from 'drizzle-kit';
export default defineConfig({
schema: './src/db/schema.ts',
out: './drizzle',
dialect: 'sqlite',
driver: 'd1-http',
dbCredentials: {
accountId: process.env.CLOUDFLARE_ACCOUNT_ID!,
databaseId: process.env.CLOUDFLARE_DATABASE_ID!,
token: process.env.CLOUDFLARE_D1_TOKEN!
}
});Database Client
// src/db/index.ts
import { drizzle } from 'drizzle-orm/d1';
import * as schema from './schema';
export function createDb(d1: D1Database) {
return drizzle(d1, { schema });
}
export type Database = ReturnType<typeof createDb>;
export * from './schema';---
Migration Workflow
Generate Migration
# Generate migration from schema changes
npx drizzle-kit generate
# Output: drizzle/0000_initial.sql
Apply Migrations Locally
# Apply to local D1
npx wrangler d1 migrations apply my-database --local
# Or via Drizzle
npx drizzle-kit migrate
Apply Migrations to Production
# Apply to remote D1
npx wrangler d1 migrations apply my-database --remote
# Preview first (dry run)
npx wrangler d1 migrations apply my-database --remote --dry-run
Migration File Example
-- drizzle/0000_initial.sql
CREATE TABLE `users` (
`id` integer PRIMARY KEY AUTOINCREMENT NOT NULL,
`email` text NOT NULL,
`name` text NOT NULL,
`role` text DEFAULT 'user',
`created_at` text DEFAULT CURRENT_TIMESTAMP,
`updated_at` text DEFAULT CURRENT_TIMESTAMP
);
CREATE UNIQUE INDEX `users_email_unique` ON `users` (`email`);
CREATE TABLE `posts` (
`id` integer PRIMARY KEY AUTOINCREMENT NOT NULL,
`title` text NOT NULL,
`content` text,
`author_id` integer REFERENCES `users`(`id`),
`published` integer DEFAULT false,
`view_count` integer DEFAULT 0,
`created_at` text DEFAULT CURRENT_TIMESTAMP
);
---
Worker Implementation
Basic Worker with Hono
// src/index.ts
import { Hono } from 'hono';
import { createDb, users, posts } from './db';
import { eq, desc } from 'drizzle-orm';
type Bindings = {
DB: D1Database;
};
const app = new Hono<{ Bindings: Bindings }>();
// Middleware to inject db
app.use('*', async (c, next)Read more
name: cloudflare-d1 description: Cloudflare D1 SQLite database with Workers, Drizzle ORM, migrations when-to-use: When working with Cloudflare D1 or Workers user-invocable: false paths: ["wrangler.toml", "src/worker*", "**/d1/**"] effort: medium
Cloudflare D1 Skill
Cloudflare D1 is a serverless SQLite database designed for Cloudflare Workers with global distribution and zero cold starts.
**Sources:** [D1 Docs](https://developers.cloudflare.com/d1/) | [Drizzle + D1](https://orm.drizzle.team/docs/connect-cloudflare-d1) | [Wrangler CLI](https://developers.cloudflare.com/workers/wrangler/)
---
Core Principle
**SQLite at the edge, migrations in version control, Drizzle for type safety.**
D1 brings SQLite's simplicity to serverless. Design for horizontal scale (multiple small databases) rather than vertical (one large database). Use Drizzle ORM for type-safe queries and migrations.
---
D1 Stack
| Component | Purpose | |-----------|---------| | **D1** | Serverless SQLite database | | **Workers** | Edge runtime for your application | | **Wrangler** | CLI for development and deployment | | **Drizzle ORM** | Type-safe ORM with migrations | | **Drizzle Kit** | Migration tooling | | **Hono** | Lightweight web framework (optional) |
---
Project Setup
Create Worker Project
# Create new project npm create cloudflare@latest my-app -- --template "worker-typescript" cd my-app # Install dependencies npm install drizzle-orm npm install -D drizzle-kit
Create D1 Database
# Create database (creates both local and remote) npx wrangler d1 create my-database # Output: # [[d1_databases]] # binding = "DB" # database_name = "my-database" # database_id = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
Configure wrangler.toml
name = "my-app" main = "src/index.ts" compatibility_date = "2024-01-01" [[d1_databases]] binding = "DB" database_name = "my-database" database_id = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" migrations_dir = "drizzle" migrations_table = "drizzle_migrations"
Generate TypeScript Types
# Generate env types from wrangler.toml
npx wrangler types
# Creates worker-configuration.d.ts:
# interface Env {
# DB: D1Database;
# }---
Drizzle ORM Setup
Schema Definition
// src/db/schema.ts
import { sqliteTable, text, integer, real, blob } from 'drizzle-orm/sqlite-core';
import { sql } from 'drizzle-orm';
export const users = sqliteTable('users', {
id: integer('id').primaryKey({ autoIncrement: true }),
email: text('email').notNull().unique(),
name: text('name').notNull(),
role: text('role', { enum: ['user', 'admin'] }).default('user'),
createdAt: text('created_at').default(sql`CURRENT_TIMESTAMP`),
updatedAt: text('updated_at').default(sql`CURRENT_TIMESTAMP`)
});
export const posts = sqliteTable('posts', {
id: integer('id').primaryKey({ autoIncrement: true }),
title: text('title').notNull(),
content: text('content'),
authorId: integer('author_id').references(() => users.id),
published: integer('published', { mode: 'boolean' }).default(false),
viewCount: integer('view_count').default(0),
createdAt: text('created_at').default(sql`CURRENT_TIMESTAMP`)
});
export const tags = sqliteTable('tags', {
id: integer('id').primaryKey({ autoIncrement: true }),
name: text('name').notNull().unique()
});
export const postTags = sqliteTable('post_tags', {
postId: integer('post_id').references(() => posts.id),
tagId: integer('tag_id').references(() => tags.id)
});
// Type exports
export type User = typeof users.$inferSelect;
export type NewUser = typeof users.$inferInsert;
export type Post = typeof posts.$inferSelect;
export type NewPost = typeof posts.$inferInsert;Drizzle Config
// drizzle.config.ts
import { defineConfig } from 'drizzle-kit';
export default defineConfig({
schema: './src/db/schema.ts',
out: './drizzle',
dialect: 'sqlite',
driver: 'd1-http',
dbCredentials: {
accountId: process.env.CLOUDFLARE_ACCOUNT_ID!,
databaseId: process.env.CLOUDFLARE_DATABASE_ID!,
token: process.env.CLOUDFLARE_D1_TOKEN!
}
});Database Client
// src/db/index.ts
import { drizzle } from 'drizzle-orm/d1';
import * as schema from './schema';
export function createDb(d1: D1Database) {
return drizzle(d1, { schema });
}
export type Database = ReturnType<typeof createDb>;
export * from './schema';---
Migration Workflow
Generate Migration
# Generate migration from schema changes npx drizzle-kit generate # Output: drizzle/0000_initial.sql
Apply Migrations Locally
# Apply to local D1 npx wrangler d1 migrations apply my-database --local # Or via Drizzle npx drizzle-kit migrate
Apply Migrations to Production
# Apply to remote D1 npx wrangler d1 migrations apply my-database --remote # Preview first (dry run) npx wrangler d1 migrations apply my-database --remote --dry-run
Migration File Example
-- drizzle/0000_initial.sql CREATE TABLE `users` ( `id` integer PRIMARY KEY AUTOINCREMENT NOT NULL, `email` text NOT NULL, `name` text NOT NULL, `role` text DEFAULT 'user', `created_at` text DEFAULT CURRENT_TIMESTAMP, `updated_at` text DEFAULT CURRENT_TIMESTAMP ); CREATE UNIQUE INDEX `users_email_unique` ON `users` (`email`); CREATE TABLE `posts` ( `id` integer PRIMARY KEY AUTOINCREMENT NOT NULL, `title` text NOT NULL, `content` text, `author_id` integer REFERENCES `users`(`id`), `published` integer DEFAULT false, `view_count` integer DEFAULT 0, `created_at` text DEFAULT CURRENT_TIMESTAMP );
---
Worker Implementation
Basic Worker with Hono
// src/index.ts
import { Hono } from 'hono';
import { createDb, users, posts } from './db';
import { eq, desc } from 'drizzle-orm';
type Bindings = {
DB: D1Database;
};
const app = new Hono<{ Bindings: Bindings }>();
// Middleware to inject db
app.use('*', async (c, next)Turn Claude Code into a self-reviewing, test-enforced engineering system that remembers context across sessions — then route work across 13 models from a single dashboard.
Repo: alinaqi/maggy
Other skills on maggy.
- /aeo-optimization
AI Engine Optimization - semantic triples, page templates, content clusters for AI citations
Open skill - /agent-teams
Claude Code Agent Teams - default team-based development with strict TDD pipeline enforcement
Open skill - /agentic-development
Build AI agents with Pydantic AI (Python) and Claude SDK (Node.js)
Open skill - /ai-models
Latest AI models reference - Claude, OpenAI, Gemini, Eleven Labs, Replicate
Open skill - /android-java
Android Java development with MVVM, ViewBinding, and Espresso testing
Open skill - /android-kotlin
Android Kotlin development with Coroutines, Jetpack Compose, Hilt, and MockK testing
Open skill

