Skip to content
Development
Command

/d1-setup

Interactive wizard to set up Cloudflare D1 database with database creation, Worker binding configuration, schema generation, and first migration. Use when user wants to create first D1 database or add D1 to existing Worker.

From plugin
secondsky-claude-skills
20466 skills46 agents66 commands
Install
$ npx -y skills add secondsky/claude-skills --agent claude-code

How it fires

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

  • Fires itselfClaude auto-loads it when your prompt matches the work.
  • You can call itInvoke it directly when you want it.
  • Slash command/d1-setup

Context preview

What this command does when you run it.

Interactive wizard to set up Cloudflare D1 database with database creation, Worker binding configuration, schema generation, and first migration. Use when user wants to create first D1 database or add D1 to existing Worker.

Command definition

d1-setup.md
name: cloudflare-d1:setup
description: Interactive wizard to set up Cloudflare D1 database with database creation, Worker binding configuration, schema generation, and first migration. Use when user wants to create first D1 database or add D1 to existing Worker.

D1 Setup Wizard

Overview

Interactive wizard for complete D1 setup: create database, configure bindings, generate schema, and run first migration.

Prerequisites

Check before starting:

  • Cloudflare account with wrangler authenticated (`wrangler whoami`)
  • Existing Worker project or willingness to create one
  • Write access to wrangler.jsonc/wrangler.toml

Steps

Step 1: Gather Requirements

Use AskUserQuestion to collect setup preferences.

**Question 1: Database Name**

  • **Prompt**: "What should your database be named?"
  • **Examples**: "my-app-db", "production-db", "users-db"
  • **Validation**: Alphanumeric + hyphens only (validate before proceeding)
  • **Store as**: `databaseName`

**Question 2: Binding Name**

  • **Prompt**: "What binding name should be used in your Worker code?"
  • **Default**: "DB"
  • **Examples**: "DB", "DATABASE", "USERS_DB"
  • **Validation**: Valid JavaScript identifier
  • **Store as**: `bindingName`

**Question 3: Schema Source**

  • **Prompt**: "Do you have an existing schema.sql file?"
  • **Options**:
  • "Yes - I have schema.sql" → Ask for path
  • "No - Generate basic schema" → Ask for table names
  • **Store as**: `hasSchema`, `schemaPath` or `tableNames`

**Question 4: Read Replication**

  • **Prompt**: "Enable read replication? (Recommended for read-heavy apps, requires paid plan)"
  • **Options**:
  • "Yes - Enable read replication"
  • "No - Single region only"
  • **Store as**: `enableReplication`

**Question 5: Data Jurisdiction** (if user is on paid plan)

  • **Prompt**: "Specify data jurisdiction for compliance? (Optional, paid plan only)"
  • **Options**:
  • "GLOBAL - Best performance (default)"
  • "EU - European Union (GDPR compliance)"
  • "US - United States"
  • **Store as**: `jurisdiction`

---

Step 2: Create Database

Build and execute wrangler command based on user inputs:

# Base command
wrangler d1 create <databaseName>

# Add jurisdiction if specified and not GLOBAL
if [jurisdiction != "GLOBAL"]:
  wrangler d1 create <databaseName> --jurisdiction <jurisdiction>

**Execute**:

# Example
wrangler d1 create my-app-db --jurisdiction EU

**Capture Output**: Extract `database_id` from output (36-character UUID)

✅ Successfully created DB 'my-app-db' (abc123-def456-ghi789-...)

Store `database_id` for next steps.

**Error Handling**:

  • If "not authenticated" → Run `wrangler login` first
  • If "database already exists" → Ask user if they want to use existing or choose different name
  • If "limit reached" → Check free tier limit (10 databases), suggest upgrade or consolidation

---

Step 3: Configure Wrangler

Check if wrangler.jsonc or wrangler.toml exists:

if [ -f "wrangler.jsonc" ]; then
  CONFIG_FILE="wrangler.jsonc"
elif [ -f "wrangler.toml" ]; then
  CONFIG_FILE="wrangler.toml"
else
  # Ask user which format to create
  CONFIG_FILE="wrangler.jsonc"  # Default to JSON
fi

**Add D1 Configuration**:

**If wrangler.jsonc**: Use Edit tool to add to `d1_databases` array (or create array if doesn't exist):

{
  "d1_databases": [
    {
      "binding": "<bindingName>",
      "database_name": "<databaseName>",
      "database_id": "<databaseId>",
      "preview_database_id": "local"
      // Conditional fields:
      // "replicate": { "enabled": true },  // if enableReplication
      // "jurisdiction": "EU"  // if jurisdiction != "GLOBAL"
    }
  ]
}

**If wrangler.toml**:

[[d1_databases]]
binding = "<bindingName>"
database_name = "<databaseName>"
database_id = "<databaseId>"

**Verify**:

# Show configuration to user
cat wrangler.jsonc | grep -A 10 "d1_databases"

**Error Handling**:

  • If wrangler config has syntax errors → Show error, offer to create fresh config
  • If binding name conflicts → Warn user, suggest unique name

---

Step 4: Setup Migrations Directory

Create migrations directory structure:

mkdir -p migrations

Confirm directory created:

ls -la migrations

---

Step 5: Generate Schema

**If user has existing schema** (`hasSchema == true`):

cp <schemaPath> migrations/0001_initial_schema.sql

**If generating schema** (`hasSchema == false`):

Ask for table details using AskUserQuestion:

  • **Prompt**: "What tables do you need? (comma-separated)"
  • **Examples**: "users, posts, comments"
  • **Store as**: `tableNames` (array)

Generate basic schema for each table:

-- migrations/0001_initial_schema.sql

-- Example for "users" table
CREATE TABLE IF NOT EXISTS users (
  id INTEGER PRIMARY KEY AUTOINCREMENT,
  email TEXT NOT NULL UNIQUE,
  name TEXT NOT NULL,
  created_at INTEGER DEFAULT (unixepoch()),
  updated_at INTEGER DEFAULT (unixepoch())
);

CREATE INDEX IF NOT EXISTS idx_users_email ON users(email);

-- Example for "posts" table
CREATE TABLE IF NOT EXISTS posts (
  id INTEGER PRIMARY KEY AUTOINCREMENT,
  user_id INTEGER NOT NULL,
  title TEXT NOT NULL,
  content TEXT,
  created_at INTEGER DEFAULT (unixepoch()),
  FOREIGN KEY (user_id) REFERENCES users(id)
);

CREATE INDEX IF NOT EXISTS idx_posts_user_id ON posts(user_id);

-- Optimize query planner
PRAGMA optimize;

**Best Practices Applied**:

  • Always use `IF NOT EXISTS`
  • INTEGER PRIMARY KEY AUTOINCREMENT for IDs
  • INTEGER for timestamps (unixepoch())
  • Indexes on foreign keys
  • PRAGMA optimize at end

**Write Schema File**:

# Use Write tool to create migrations/0001_initial_schema.sql

---

Step 6: Apply First Migration

**Test Locally First** (recommended):

wrangler d1 migrations apply <databaseName> --local

Check for errors. If successful, proceed to remote.

**Apply to Remote**:

wrangler d1 migrations apply <databaseName> --remote

**Verify**:

Read more
Ships withsecondsky-claude-skills

142 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, auto-invoked
Stats
204
Stars
0
Views
30
Forks
Active
Maintenance
TypeScript
Language
MIT
License
1h ago
Last commit
9mo ago
Created

Repo: secondsky/claude-skills