home / skills / secondsky / claude-skills / cloudflare-workers-dev-experience

cloudflare-workers-dev-experience skill

/plugins/cloudflare-workers/skills/cloudflare-workers-dev-experience

This skill guides local Cloudflare Workers development with Wrangler and Miniflare, enabling quick setup, config validation, and effective debugging.

npx playbooks add skill secondsky/claude-skills --skill cloudflare-workers-dev-experience

Review the files below or copy the command above to add this skill to your agents.

Files (7)
SKILL.md
5.5 KB
---
name: workers-dev-experience
description: Cloudflare Workers local development with Wrangler, Miniflare, hot reload, debugging. Use for project setup, wrangler.jsonc configuration, or encountering local dev, HMR, binding simulation errors.
---

# Cloudflare Workers Developer Experience

Local development setup with Wrangler, Miniflare, and modern tooling.

## Quick Start

```bash
# Create new project
bunx create-cloudflare@latest my-worker

# Or from scratch
mkdir my-worker && cd my-worker
bun init -y
bun add -d wrangler @cloudflare/workers-types

# Start local development
bunx wrangler dev
```

## Essential wrangler.jsonc

```jsonc
{
  "$schema": "node_modules/wrangler/config-schema.json",
  "name": "my-worker",
  "main": "src/index.ts",
  "compatibility_date": "2024-12-01",

  // Development settings
  "dev": {
    "port": 8787,
    "local_protocol": "http"
  },

  // Environment variables (non-secret)
  "vars": {
    "ENVIRONMENT": "development"
  },

  // Bindings
  "kv_namespaces": [
    { "binding": "KV", "id": "abc123", "preview_id": "def456" }
  ],

  "d1_databases": [
    { "binding": "DB", "database_id": "xyz789", "database_name": "my-db" }
  ],

  "r2_buckets": [
    { "binding": "BUCKET", "bucket_name": "my-bucket" }
  ]
}
```

## Critical Rules

1. **Always use `wrangler dev` for local testing** - Simulates Cloudflare runtime accurately
2. **Set `compatibility_date`** - Controls runtime behavior, update quarterly
3. **Use preview IDs for local dev** - Separate from production bindings
4. **Configure TypeScript properly** - Use `@cloudflare/workers-types`
5. **Enable source maps** - Better error stacks in development

## Top 6 Errors Prevented

| Error | Symptom | Prevention |
|-------|---------|------------|
| Module not found | Import errors on deploy | Set `"moduleResolution": "bundler"` in tsconfig |
| Binding undefined | `env.KV is undefined` locally | Add `preview_id` to KV namespace config |
| HMR not working | Changes not reflecting | Check port conflicts, use `--local` flag |
| D1 schema mismatch | Queries fail locally | Run migrations on local DB |
| Type errors | Missing binding types | Generate types with `wrangler types` |
| CORS issues | Browser blocking requests | Add CORS headers in dev handler |

## Local Development Workflow

```bash
# Start dev server (recommended)
bunx wrangler dev

# With live reload
bunx wrangler dev --live-reload

# Remote mode (use actual Cloudflare services)
bunx wrangler dev --remote

# Specify environment
bunx wrangler dev --env staging

# Custom port
bunx wrangler dev --port 3000
```

## TypeScript Configuration

**tsconfig.json**:
```json
{
  "compilerOptions": {
    "target": "ES2022",
    "module": "ES2022",
    "moduleResolution": "bundler",
    "lib": ["ES2022"],
    "types": ["@cloudflare/workers-types"],
    "strict": true,
    "noEmit": true,
    "skipLibCheck": true,
    "allowSyntheticDefaultImports": true,
    "forceConsistentCasingInFileNames": true
  },
  "include": ["src/**/*"],
  "exclude": ["node_modules"]
}
```

## Package.json Scripts

```json
{
  "scripts": {
    "dev": "wrangler dev",
    "deploy": "wrangler deploy",
    "deploy:staging": "wrangler deploy --env staging",
    "deploy:production": "wrangler deploy --env production",
    "test": "vitest",
    "test:watch": "vitest --watch",
    "type-check": "tsc --noEmit",
    "lint": "eslint src/",
    "types": "wrangler types",
    "tail": "wrangler tail",
    "db:migrate": "wrangler d1 migrations apply DB",
    "db:studio": "wrangler d1 execute DB --local --command 'SELECT 1'"
  }
}
```

## Debugging

### Console Logging

```typescript
// Development-only logging
export default {
  async fetch(request: Request, env: Env): Promise<Response> {
    if (env.ENVIRONMENT === 'development') {
      console.log('Request:', request.method, request.url);
      console.log('Headers:', Object.fromEntries(request.headers));
    }

    // Handler logic...
  }
};
```

### Using wrangler tail

```bash
# Real-time logs from deployed worker
wrangler tail

# Filter by status
wrangler tail --status error

# Filter by method
wrangler tail --method POST

# JSON format for parsing
wrangler tail --format json
```

### VS Code Debugging

**.vscode/launch.json**:
```json
{
  "version": "0.2.0",
  "configurations": [
    {
      "name": "Wrangler Dev",
      "type": "node",
      "request": "launch",
      "runtimeExecutable": "bunx",
      "runtimeArgs": ["wrangler", "dev", "--inspector-port", "9229"],
      "skipFiles": ["<node_internals>/**"],
      "sourceMaps": true
    }
  ]
}
```

## When to Load References

Load specific references based on the task:

- **Setting up project?** → Load `references/local-development.md` for complete setup guide
- **Configuring wrangler?** → Load `references/wrangler-config.md` for all configuration options
- **Debugging issues?** → Load `references/debugging-tools.md` for debugging techniques

## Templates

| Template | Purpose | Use When |
|----------|---------|----------|
| `templates/wrangler-config.jsonc` | Complete wrangler config | Starting new project |
| `templates/dev-script.ts` | Development utilities | Adding dev helpers |

## Scripts

| Script | Purpose | Command |
|--------|---------|---------|
| `scripts/dev-setup.sh` | Initialize dev environment | `./dev-setup.sh` |

## Resources

- Wrangler CLI: https://developers.cloudflare.com/workers/wrangler/
- Configuration: https://developers.cloudflare.com/workers/wrangler/configuration/
- Local Development: https://developers.cloudflare.com/workers/testing/local-development/

Overview

This skill provides a focused developer experience for Cloudflare Workers local development using Wrangler, Miniflare, hot reload, and debugging tools. It helps set up projects, configure wrangler.jsonc and TypeScript, and troubleshoot local binding, HMR, and runtime issues. The goal is fast, reliable iteration that closely mirrors Cloudflare’s runtime.

How this skill works

The skill inspects your project configuration (wrangler.jsonc, tsconfig.json, package.json) and recommends fixes for common local-dev failures. It validates bindings, preview IDs, compatibility_date, moduleResolution, and source maps. For runtime issues it guides through using wrangler dev, live-reload flags, wrangler tail, and VS Code inspector-based debugging.

When to use it

  • Starting a new Workers project or integrating with React/Tailwind/AI stacks
  • Configuring wrangler.jsonc, KV/D1/R2 bindings, or environment vars for local dev
  • Troubleshooting hot module reload, missing bindings, or TypeScript bundling errors
  • Preparing local migrations or simulating production services with preview IDs
  • Setting up source maps and VS Code debugging for better error stacks

Best practices

  • Always run wrangler dev for local testing to emulate the Cloudflare runtime
  • Set compatibility_date and update it regularly to control runtime behavior
  • Use preview_id entries for KV and other bindings in local config to avoid production collisions
  • Enable source maps and include @cloudflare/workers-types in tsconfig for accurate types
  • Set moduleResolution to 'bundler' to prevent module-not-found errors when deploying

Example use cases

  • Create a new worker with bunx create-cloudflare and validate wrangler.jsonc bindings
  • Fix env.KV undefined by adding preview_id and regenerating wrangler types
  • Enable live reload with bunx wrangler dev --live-reload and troubleshoot port conflicts
  • Run local D1 migrations and validate queries before deploying to staging
  • Attach VS Code to wrangler dev using the inspector port for step-through debugging

FAQ

Why is env.KV undefined locally?

Ensure the KV namespace in wrangler.jsonc includes a preview_id and run wrangler dev so local bindings use preview resources.

HMR not reflecting changes — what should I check?

Verify no port conflict, use --live-reload, confirm dev server is running, and ensure bundler moduleResolution so rebuilds produce updated bundles.