Agent skill

Cloudflare

by einverne in einverne/dotfiles

Guide for building applications on Cloudflare's edge platform.

MITAuto-check passedBackend & APIs

Install Cloudflare

skills CLI
$ npx skills add einverne/dotfiles --skill cloudflare -a claude-code

Project install by default; add -g for ~/.claude/skills/.

GitHub CLI
$ gh skill install einverne/dotfiles cloudflare --agent claude-code

Project scope by default; add --scope user for a personal install. Needs GitHub CLI 2.90.0 or later (public preview).

Manual copy
$ git clone --depth 1 https://github.com/einverne/dotfiles.git skills-src && mkdir -p .claude/skills && cp -r skills-src/claude/skills/cloudflare .claude/skills/cloudflare && rm -rf skills-src

Use ~/.claude/skills/ instead of .claude/skills for a personal install. The folder must contain SKILL.md.

Claude Code skills documentation · loads skills from .claude/skills/

Facts

Skill name
cloudflare
GitHub stars
121
Token cost
~6.7k tokens
SKILL.md length
1,050 words
Files
1
Skills in repo
39
Repo updated
First seen
Licence
MIT

At a glance

Guide for building applications on Cloudflare's edge platform.

  • Works in 5 steps: Minimize Cold Starts: Keep Workers… → Use Bindings Over Fetch: Direct bindings… → Edge Caching: Leverage KV and Cache API… → …
  • Implementing serverless functions (Workers)
  • SKILL.md covers When to Use This Skill, Core Concepts, Getting Started with Workers and Storage Products, plus 4 more sections
  • Calls wrangler, npm and npx; reaches gateway.ai.cloudflare.com; needs JWT_SECRET and OPENAI_API_KEY

What it does

Cloudflare is an agent skill from einverne/dotfiles. Guide for building applications on Cloudflare's edge platform. Use when implementing serverless functions (Workers), edge databases (D1), storage (R2, KV), real-time apps (Durable Objects), AI features (Workers AI, AI Gateway), static sites (Pages), or any edge computing solutions.

Its SKILL.md is about 6.7k tokens, which your agent loads only when the skill is triggered. It is a single SKILL.md file with no bundled scripts.

It sits in Backend & APIs, covering Static sites and blogs and Serverless. It works with Cloudflare, Cloudflare Durable Objects, Workers AI and SQLite. The repository describes itself as: my personal dotfiles managed by dotbot, zinit. The licence is MIT.

When your agent uses it

  • Implementing serverless functions (Workers)
  • Edge databases (D1)
  • Real-time apps (Durable Objects)
  • AI features (Workers AI

Example prompts

  • “/cloudflare”

Requirements

  • Python 3
  • Node.js
  • A credential in OPENAI_API_KEY

Workflow steps

5 steps, taken from the first numbered list in SKILL.md.

  1. Minimize Cold Starts: Keep Workers lightweight (<1MB bundled)
  2. Use Bindings Over Fetch: Direct bindings are faster than HTTP calls
  3. Edge Caching: Leverage KV and Cache API for frequently accessed data
  4. Batch Operations: Use D1 batch for multiple queries
  5. Stream Large Responses: Use Response.body streams for large files

What it can do on your machine

Read from SKILL.md and the folder at commit c6c0686. It shows what the files ask for, not the result of running them.

  • Tool permissions

    Pre-approves nothing: there is no allowed-tools line, so your agent's usual permission prompts apply.

    From allowed-tools in the SKILL.md frontmatter.

  • Runs code

    Shell commands in SKILL.md call:

    • wrangler
    • npm
    • npx

    From the folder's file list and the shell code blocks in SKILL.md.

  • Network

    Hosts in commands or code, which the agent is likely to contact:

    • gateway.ai.cloudflare.com

    Also links to:

    • developers.cloudflare.com
    • discord.cloudflare.com
    • github.com
    • cloudflarestatus.com

    From URLs in SKILL.md, links to its own repository left out.

  • Credentials

    Names these keys or tokens, usually read from environment variables:

    • JWT_SECRET
    • OPENAI_API_KEY

    From names ending in _API_KEY, _TOKEN, _SECRET, _KEY or _PASSWORD in SKILL.md.

Context cost

Cloudflare loads about 6.7k tokens when it runs. Until then it costs about 73 tokens; SKILL.md has 1,050 words of instructions outside code blocks.

Always · name and description, kept in context so the agent knows when to use it
~73
When it runs · the whole SKILL.md, loaded when a task matches
~6.7k

Estimates: characters ÷ 4, the usual rule of thumb; real counts depend on the model's tokenizer. Scripts and assets cost tokens only if the agent reads them.

Safety

Auto-check passed

The automated check found no risky patterns in SKILL.md.

Automated static check — not a guarantee. Review scripts before installing. It scans the text of SKILL.md for risky patterns (piping downloads into a shell, reading credential files, hidden Unicode, destructive commands); files beside SKILL.md are not scanned.

SKILL.md

The full file from einverne/dotfiles at commit c6c0686, republished under its MIT licence (© einverne). 1,050 words, ~6,670 tokens.

Download SKILL.mdSave it as .claude/skills/cloudflare/SKILL.md (or your agent's skills folder).
name
cloudflare
description
Guide for building applications on Cloudflare's edge platform. Use when implementing serverless functions (Workers), edge databases (D1), storage (R2, KV), real-time apps (Durable Objects), AI features (Workers AI, AI Gateway), static sites (Pages), or any edge computing solutions.
license
MIT
version
1.0.0

Cloudflare Developer Platform Skill

Cloudflare Developer Platform is a comprehensive edge computing ecosystem for building full-stack applications on Cloudflare's global network. It includes serverless functions, databases, storage, AI/ML capabilities, and static site hosting.

When to Use This Skill

Use this skill when:

  • Building serverless applications on the edge
  • Implementing edge databases (D1 SQLite)
  • Working with object storage (R2) or key-value stores (KV)
  • Creating real-time applications with WebSockets (Durable Objects)
  • Integrating AI/ML capabilities (Workers AI, AI Gateway, Agents)
  • Deploying static sites with serverless functions (Pages)
  • Building full-stack applications with frameworks (Next.js, Remix, Astro, etc.)
  • Implementing message queues and background jobs (Queues)
  • Optimizing for global performance and low latency

Core Concepts

Edge Computing Platform

Cloudflare's Edge Network: Code runs on servers globally distributed across 300+ cities, executing requests from the nearest location for ultra-low latency.

Key Components:

  • Workers: Serverless functions on the edge
  • D1: SQLite database with global read replication
  • KV: Distributed key-value store with eventual consistency
  • R2: Object storage with zero egress fees
  • Durable Objects: Stateful compute with WebSocket support
  • Queues: Message queue system for async processing
  • Pages: Static site hosting with serverless functions
  • Workers AI: Run AI models on the edge
  • AI Gateway: Unified interface for AI providers
Execution Model

V8 Isolates: Lightweight execution environments (faster than containers) with:

  • Millisecond cold starts
  • Zero infrastructure management
  • Automatic scaling
  • Pay-per-request pricing

Handler Types:

  • fetch: HTTP requests
  • scheduled: Cron jobs
  • queue: Message processing
  • tail: Log aggregation
  • email: Email handling
  • alarm: Durable Object timers

Getting Started with Workers

Installation
bash
# Install Wrangler CLI
npm install -g wrangler

# Login to Cloudflare
wrangler login

# Create new project
wrangler init my-worker
cd my-worker

# Start local development
wrangler dev

# Deploy to production
wrangler deploy
Basic Worker
typescript
// src/index.ts
export default {
  async fetch(request: Request, env: Env): Promise<Response> {
    return new Response('Hello from Cloudflare Workers!');
  }
};
Configuration (wrangler.toml)
toml
name = "my-worker"
main = "src/index.ts"
compatibility_date = "2024-01-01"

# Environment variables
[vars]
ENVIRONMENT = "production"

# Bindings (added per product below)
Language Support
  • JavaScript/TypeScript: Primary language (full Node.js compatibility)
  • Python: Beta support via Workers Python
  • Rust: Compile to WebAssembly

Storage Products

D1 (SQLite Database)

Use Cases: Relational data, complex queries, ACID transactions

Setup:

bash
# Create database
wrangler d1 create my-database

# Add to wrangler.toml
[[d1_databases]]
binding = "DB"
database_name = "my-database"
database_id = "YOUR_DATABASE_ID"

# Generate and apply schema
wrangler d1 execute my-database --file=./schema.sql

Usage:

typescript
export default {
  async fetch(request: Request, env: Env) {
    // Query
    const result = await env.DB.prepare(
      "SELECT * FROM users WHERE id = ?"
    ).bind(userId).first();

    // Insert
    await env.DB.prepare(
      "INSERT INTO users (name, email) VALUES (?, ?)"
    ).bind("Alice", "alice@example.com").run();

    // Batch (atomic)
    await env.DB.batch([
      env.DB.prepare("UPDATE accounts SET balance = balance - 100 WHERE id = ?").bind(user1),
      env.DB.prepare("UPDATE accounts SET balance = balance + 100 WHERE id = ?").bind(user2)
    ]);

    return new Response(JSON.stringify(result));
  }
};

Key Features:

  • Global read replication (low-latency reads)
  • Single-writer consistency
  • Standard SQLite syntax
  • 25GB database size limit
KV (Key-Value Store)

Use Cases: Cache, sessions, feature flags, rate limiting

Setup:

bash
# Create namespace
wrangler kv:namespace create MY_KV

# Add to wrangler.toml
[[kv_namespaces]]
binding = "KV"
id = "YOUR_NAMESPACE_ID"

Usage:

typescript
export default {
  async fetch(request: Request, env: Env) {
    // Put with TTL
    await env.KV.put("session:token", JSON.stringify(data), {
      expirationTtl: 3600 // 1 hour
    });

    // Get
    const data = await env.KV.get("session:token", "json");

    // Delete
    await env.KV.delete("session:token");

    // List with prefix
    const list = await env.KV.list({ prefix: "user:123:" });

    return new Response(JSON.stringify(data));
  }
};

Key Features:

  • Sub-millisecond reads (edge-cached)
  • Eventual consistency (~60 seconds globally)
  • 25MB value size limit
  • Automatic expiration (TTL)
R2 (Object Storage)

Use Cases: File storage, media hosting, backups, static assets

Setup:

bash
# Create bucket
wrangler r2 bucket create my-bucket

# Add to wrangler.toml
[[r2_buckets]]
binding = "R2_BUCKET"
bucket_name = "my-bucket"

Usage:

typescript
export default {
  async fetch(request: Request, env: Env) {
    // Put object
    await env.R2_BUCKET.put("path/to/file.jpg", fileBuffer, {
      httpMetadata: {
        contentType: "image/jpeg"
      }
    });

    // Get object
    const object = await env.R2_BUCKET.get("path/to/file.jpg");
    if (!object) {
      return new Response("Not found", { status: 404 });
    }

    // Stream response
    return new Response(object.body, {
      headers: {
        "Content-Type": object.httpMetadata?.contentType || "application/octet-stream"
      }
    });

    // Delete
    await env.R2_BUCKET.delete("path/to/file.jpg");

    // List
    const list = await env.R2_BUCKET.list({ prefix: "uploads/" });
  }
};

Key Features:

  • S3-compatible API
  • Zero egress fees (huge cost advantage)
  • Unlimited storage
  • 5TB object size limit
  • Multipart upload support
Durable Objects

Use Cases: Real-time apps, WebSockets, coordination, stateful logic

Setup:

toml
# wrangler.toml
[[durable_objects.bindings]]
name = "COUNTER"
class_name = "Counter"
script_name = "my-worker"

Usage:

typescript
// Define Durable Object class
export class Counter {
  state: DurableObjectState;

  constructor(state: DurableObjectState, env: Env) {
    this.state = state;
  }

  async fetch(request: Request) {
    // Get current count
    let count = (await this.state.storage.get<number>('count')) || 0;

    // Increment
    count++;
    await this.state.storage.put('count', count);

    return new Response(JSON.stringify({ count }));
  }
}

// Use in Worker
export default {
  async fetch(request: Request, env: Env) {
    // Get Durable Object instance
    const id = env.COUNTER.idFromName("global-counter");
    const counter = env.COUNTER.get(id);

    // Forward request
    return counter.fetch(request);
  }
};

WebSocket Example:

typescript
export class ChatRoom {
  state: DurableObjectState;
  sessions: Set<WebSocket>;

  constructor(state: DurableObjectState) {
    this.state = state;
    this.sessions = new Set();
  }

  async fetch(request: Request) {
    const pair = new WebSocketPair();
    const [client, server] = Object.values(pair);

    this.state.acceptWebSocket(server);
    this.sessions.add(server);

    return new Response(null, { status: 101, webSocket: client });
  }

  async webSocketMessage(ws: WebSocket, message: string) {
    // Broadcast to all connected clients
    for (const session of this.sessions) {
      session.send(message);
    }
  }

  async webSocketClose(ws: WebSocket) {
    this.sessions.delete(ws);
  }
}

Key Features:

  • Single-instance coordination (strong consistency)
  • Persistent storage (1GB limit on paid plans)
  • WebSocket support
  • Automatic hibernation for inactive objects
Queues

Use Cases: Background jobs, email sending, async processing

Setup:

toml
# wrangler.toml
[[queues.producers]]
binding = "MY_QUEUE"
queue = "my-queue"

[[queues.consumers]]
queue = "my-queue"
max_batch_size = 10
max_batch_timeout = 30

Usage:

typescript
// Producer: Send messages
export default {
  async fetch(request: Request, env: Env) {
    await env.MY_QUEUE.send({
      type: 'email',
      to: 'user@example.com',
      subject: 'Welcome!'
    });

    return new Response('Message queued');
  }
};

// Consumer: Process messages
export default {
  async queue(batch: MessageBatch<any>, env: Env) {
    for (const message of batch.messages) {
      try {
        await processMessage(message.body);
        message.ack(); // Acknowledge success
      } catch (error) {
        message.retry(); // Retry on failure
      }
    }
  }
};

Key Features:

  • At-least-once delivery
  • Automatic retries (exponential backoff)
  • Dead-letter queue support
  • Batch processing

AI Products

Workers AI

Use Cases: Run AI models directly on the edge

Setup:

toml
# wrangler.toml
[ai]
binding = "AI"

Usage:

typescript
export default {
  async fetch(request: Request, env: Env) {
    // Text generation
    const response = await env.AI.run('@cf/meta/llama-3-8b-instruct', {
      messages: [
        { role: 'user', content: 'What is edge computing?' }
      ]
    });

    // Image classification
    const imageResponse = await env.AI.run('@cf/microsoft/resnet-50', {
      image: imageBuffer
    });

    // Text embeddings
    const embeddings = await env.AI.run('@cf/baai/bge-base-en-v1.5', {
      text: 'Hello world'
    });

    return new Response(JSON.stringify(response));
  }
};

Available Models:

  • LLMs: Llama 3, Mistral, Gemma, Qwen
  • Image: Stable Diffusion, DALL-E, ResNet
  • Embeddings: BGE, GTE
  • Translation, summarization, sentiment analysis
AI Gateway

Use Cases: Unified interface for AI providers with caching, rate limiting, analytics

Setup:

typescript
// OpenAI via AI Gateway
const response = await fetch(
  'https://gateway.ai.cloudflare.com/v1/{account_id}/{gateway_id}/openai/chat/completions',
  {
    method: 'POST',
    headers: {
      'Authorization': `Bearer ${env.OPENAI_API_KEY}`,
      'Content-Type': 'application/json'
    },
    body: JSON.stringify({
      model: 'gpt-4',
      messages: [{ role: 'user', content: 'Hello!' }]
    })
  }
);

Features:

  • Request caching (reduce costs)
  • Rate limiting
  • Analytics and logging
  • Supports OpenAI, Anthropic, HuggingFace, etc.
Agents

Use Cases: Build AI agents with tools and workflows

typescript
import { Agent } from '@cloudflare/agents';

export default {
  async fetch(request: Request, env: Env) {
    const agent = new Agent({
      model: '@cf/meta/llama-3-8b-instruct',
      tools: [
        {
          name: 'get_weather',
          description: 'Get current weather',
          parameters: {
            type: 'object',
            properties: {
              location: { type: 'string' }
            }
          },
          handler: async ({ location }) => {
            // Fetch weather data
            return { temperature: 72, conditions: 'sunny' };
          }
        }
      ]
    });

    const result = await agent.run('What is the weather in San Francisco?');
    return new Response(JSON.stringify(result));
  }
};
AI Search (RAG)

Use Cases: Build retrieval-augmented generation applications

typescript
import { VectorizeIndex } from '@cloudflare/workers-types';

export default {
  async fetch(request: Request, env: Env) {
    // Generate embeddings
    const embeddings = await env.AI.run('@cf/baai/bge-base-en-v1.5', {
      text: query
    });

    // Search vector database
    const results = await env.VECTORIZE_INDEX.query(embeddings.data[0], {
      topK: 5
    });

    // Generate response with context
    const response = await env.AI.run('@cf/meta/llama-3-8b-instruct', {
      messages: [
        {
          role: 'system',
          content: `Context: ${results.matches.map(m => m.metadata.text).join('\n')}`
        },
        { role: 'user', content: query }
      ]
    });

    return new Response(JSON.stringify(response));
  }
};

Cloudflare Pages

Static Sites + Serverless Functions

Deployment:

bash
# Deploy via Git (recommended)
# Connect GitHub repo in Cloudflare dashboard

# Or deploy via CLI
wrangler pages deploy ./dist
Pages Functions

Directory-based routing in functions/:

functions/
├── api/
│   ├── users/
│   │   └── [id].ts       # /api/users/:id
│   └── posts.ts          # /api/posts
└── _middleware.ts        # Global middleware

Example Function:

typescript
// functions/api/users/[id].ts
export async function onRequestGet(context) {
  const { params, env } = context;
  const user = await env.DB.prepare(
    "SELECT * FROM users WHERE id = ?"
  ).bind(params.id).first();

  return new Response(JSON.stringify(user), {
    headers: { 'Content-Type': 'application/json' }
  });
}

Middleware:

typescript
// functions/_middleware.ts
export async function onRequest(context) {
  const start = Date.now();
  const response = await context.next();
  const duration = Date.now() - start;

  console.log(`${context.request.method} ${context.request.url} - ${duration}ms`);
  return response;
}
Framework Support

Next.js:

bash
npx create-next-app@latest my-app
cd my-app
npm install -D @cloudflare/next-on-pages
npx @cloudflare/next-on-pages
wrangler pages deploy .vercel/output/static

Remix:

bash
npx create-remix@latest --template cloudflare/remix

Astro:

bash
npm create astro@latest
# Select "Cloudflare" adapter during setup

SvelteKit:

bash
npm create svelte@latest
npm install -D @sveltejs/adapter-cloudflare

Wrangler CLI Essentials

Core Commands
bash
# Development
wrangler dev                    # Local development server
wrangler dev --remote          # Dev on real Cloudflare infrastructure

# Deployment
wrangler deploy                # Deploy to production
wrangler deploy --dry-run     # Preview changes without deploying

# Logs
wrangler tail                  # Real-time logs
wrangler tail --format pretty # Formatted logs

# Versions
wrangler deployments list      # List deployments
wrangler rollback [version]   # Rollback to previous version

# Secrets
wrangler secret put SECRET_NAME    # Add secret
wrangler secret list               # List secrets
wrangler secret delete SECRET_NAME # Delete secret
Project Management
bash
# Create projects
wrangler init my-worker        # Create Worker
wrangler pages project create  # Create Pages project

# Database
wrangler d1 create my-db           # Create D1 database
wrangler d1 execute my-db --file=schema.sql
wrangler d1 execute my-db --command="SELECT * FROM users"

# KV
wrangler kv:namespace create MY_KV
wrangler kv:key put --binding=MY_KV "key" "value"
wrangler kv:key get --binding=MY_KV "key"

# R2
wrangler r2 bucket create my-bucket
wrangler r2 object put my-bucket/file.txt --file=./file.txt

Integration Patterns

Full-Stack Application Architecture
┌─────────────────────────────────────────┐
│         Cloudflare Pages (Frontend)      │
│    Next.js / Remix / Astro / SvelteKit  │
└──────────────────┬──────────────────────┘
                   │
┌──────────────────▼──────────────────────┐
│      Workers (API Layer / BFF)          │
│    - Routing                             │
│    - Authentication                      │
│    - Business logic                      │
└─┬──────┬──────┬──────┬──────┬───────────┘
  │      │      │      │      │
  ▼      ▼      ▼      ▼      ▼
┌────┐ ┌────┐ ┌────┐ ┌────┐ ┌────────────┐
│ D1 │ │ KV │ │ R2 │ │ DO │ │ Workers AI │
└────┘ └────┘ └────┘ └────┘ └────────────┘
Polyglot Storage Pattern
typescript
export default {
  async fetch(request: Request, env: Env) {
    const url = new URL(request.url);

    // KV: Fast cache
    const cached = await env.KV.get(url.pathname);
    if (cached) return new Response(cached);

    // D1: Structured data
    const user = await env.DB.prepare(
      "SELECT * FROM users WHERE id = ?"
    ).bind(userId).first();

    // R2: Media files
    const avatar = await env.R2_BUCKET.get(`avatars/${user.id}.jpg`);

    // Durable Objects: Real-time coordination
    const chat = env.CHAT_ROOM.get(env.CHAT_ROOM.idFromName(roomId));

    // Queue: Async processing
    await env.EMAIL_QUEUE.send({ to: user.email, template: 'welcome' });

    return new Response(JSON.stringify({ user, avatar }));
  }
};
Authentication Pattern
typescript
import { verifyJWT, createJWT } from './jwt';

export default {
  async fetch(request: Request, env: Env) {
    const url = new URL(request.url);

    // Login
    if (url.pathname === '/api/login') {
      const { email, password } = await request.json();

      const user = await env.DB.prepare(
        "SELECT * FROM users WHERE email = ?"
      ).bind(email).first();

      if (!user || !await verifyPassword(password, user.password_hash)) {
        return new Response('Invalid credentials', { status: 401 });
      }

      const token = await createJWT({ userId: user.id }, env.JWT_SECRET);

      return new Response(JSON.stringify({ token }), {
        headers: { 'Content-Type': 'application/json' }
      });
    }

    // Protected route
    const authHeader = request.headers.get('Authorization');
    if (!authHeader) {
      return new Response('Unauthorized', { status: 401 });
    }

    const token = authHeader.replace('Bearer ', '');
    const payload = await verifyJWT(token, env.JWT_SECRET);

    // Store session in KV
    await env.KV.put(`session:${payload.userId}`, JSON.stringify(payload), {
      expirationTtl: 86400 // 24 hours
    });

    return new Response('Authenticated');
  }
};
Cache Strategy
typescript
export default {
  async fetch(request: Request, env: Env) {
    const cache = caches.default;
    const cacheKey = new Request(request.url);

    // Check cache
    let response = await cache.match(cacheKey);
    if (response) return response;

    // Check KV (distributed cache)
    const kvCached = await env.KV.get(request.url);
    if (kvCached) {
      response = new Response(kvCached);
      await cache.put(cacheKey, response.clone());
      return response;
    }

    // Fetch from origin (D1, R2, etc.)
    const data = await fetchFromOrigin(request, env);
    response = new Response(data);

    // Store in both caches
    await cache.put(cacheKey, response.clone());
    await env.KV.put(request.url, data, { expirationTtl: 3600 });

    return response;
  }
};

Best Practices

Performance
  1. Minimize Cold Starts: Keep Workers lightweight (<1MB bundled)
  2. Use Bindings Over Fetch: Direct bindings are faster than HTTP calls
  3. Edge Caching: Leverage KV and Cache API for frequently accessed data
  4. Batch Operations: Use D1 batch for multiple queries
  5. Stream Large Responses: Use Response.body streams for large files
Security
  1. Secrets Management: Use wrangler secret for API keys
  2. Environment Isolation: Separate production/staging/development
  3. Input Validation: Sanitize user input
  4. Rate Limiting: Use KV or Durable Objects for rate limiting
  5. CORS: Configure proper CORS headers
Show full SKILL.md (425 more words)Show less
Cost Optimization
  1. R2 for Large Files: Zero egress fees vs S3
  2. KV for Caching: Reduce D1/R2 requests
  3. Request Deduplication: Cache identical requests
  4. Efficient Queries: Index D1 tables properly
  5. Monitor Usage: Use Cloudflare Analytics
Development Workflow
  1. Local Development: Use wrangler dev for testing
  2. Type Safety: Use TypeScript with @cloudflare/workers-types
  3. Testing: Use Vitest with unstable_dev()
  4. CI/CD: GitHub Actions with cloudflare/wrangler-action
  5. Gradual Deployments: Use percentage-based rollouts

Common Patterns

API Gateway
typescript
import { Hono } from 'hono';

const app = new Hono();

app.get('/api/users/:id', async (c) => {
  const user = await c.env.DB.prepare(
    "SELECT * FROM users WHERE id = ?"
  ).bind(c.req.param('id')).first();

  return c.json(user);
});

app.post('/api/users', async (c) => {
  const { name, email } = await c.req.json();

  await c.env.DB.prepare(
    "INSERT INTO users (name, email) VALUES (?, ?)"
  ).bind(name, email).run();

  return c.json({ success: true }, 201);
});

export default app;
Image Transformation
typescript
export default {
  async fetch(request: Request, env: Env) {
    const url = new URL(request.url);
    const imageKey = url.pathname.replace('/images/', '');

    // Get from R2
    const object = await env.R2_BUCKET.get(imageKey);
    if (!object) {
      return new Response('Not found', { status: 404 });
    }

    // Transform with Cloudflare Images
    return new Response(object.body, {
      headers: {
        'Content-Type': object.httpMetadata?.contentType || 'image/jpeg',
        'Cache-Control': 'public, max-age=86400',
        'cf-image-resize': JSON.stringify({
          width: 800,
          height: 600,
          fit: 'cover'
        })
      }
    });
  }
};
Rate Limiting (KV)
typescript
async function rateLimit(ip: string, env: Env): Promise<boolean> {
  const key = `ratelimit:${ip}`;
  const limit = 100; // requests per minute
  const window = 60; // seconds

  const current = await env.KV.get(key);
  const count = current ? parseInt(current) : 0;

  if (count >= limit) {
    return false; // Rate limit exceeded
  }

  await env.KV.put(key, (count + 1).toString(), {
    expirationTtl: window
  });

  return true;
}

export default {
  async fetch(request: Request, env: Env) {
    const ip = request.headers.get('CF-Connecting-IP') || 'unknown';

    if (!await rateLimit(ip, env)) {
      return new Response('Rate limit exceeded', { status: 429 });
    }

    return new Response('OK');
  }
};
Scheduled Jobs
toml
# wrangler.toml
[triggers]
crons = ["0 0 * * *"] # Daily at midnight
typescript
export default {
  async scheduled(event: ScheduledEvent, env: Env) {
    // Cleanup old sessions
    const sessions = await env.KV.list({ prefix: 'session:' });
    for (const key of sessions.keys) {
      const session = await env.KV.get(key.name, 'json');
      if (session.expiresAt < Date.now()) {
        await env.KV.delete(key.name);
      }
    }
  }
};

Troubleshooting

Common Issues

"Module not found" errors

  • Ensure dependencies are in package.json
  • Run npm install before deploying
  • Check compatibility_date in wrangler.toml

Database connection errors (D1)

  • Verify database_id in wrangler.toml
  • Check database exists: wrangler d1 list
  • Run migrations: wrangler d1 execute DB --file=schema.sql

KV not found errors

  • Create namespace: wrangler kv:namespace create MY_KV
  • Add binding to wrangler.toml
  • Deploy after configuration changes

Cold start timeout

  • Reduce bundle size (<1MB ideal)
  • Remove unnecessary dependencies
  • Use dynamic imports for large libraries

CORS errors

  • Add CORS headers to responses:
    typescript
    return new Response(data, {
      headers: {
        'Access-Control-Allow-Origin': '*',
        'Access-Control-Allow-Methods': 'GET, POST, OPTIONS',
        'Access-Control-Allow-Headers': 'Content-Type'
      }
    });

Deployment fails

  • Check wrangler version: wrangler --version
  • Verify authentication: wrangler whoami
  • Review build errors in console output
Debugging
bash
# Real-time logs
wrangler tail

# Local debugging with breakpoints
wrangler dev --local

# Remote debugging
wrangler dev --remote

# Check deployment status
wrangler deployments list

Decision Matrix

NeedChoose
Sub-millisecond readsKV
SQL queriesD1
Large files (>25MB)R2
Real-time WebSocketsDurable Objects
Async background jobsQueues
ACID transactionsD1
Strong consistencyDurable Objects
Zero egress costsR2
AI inferenceWorkers AI
Static site hostingPages
Serverless functionsWorkers
Multi-provider AIAI Gateway

Framework-Specific Guides

Next.js
  • Use @cloudflare/next-on-pages adapter
  • Configure next.config.js for edge runtime
  • Deploy via wrangler pages deploy
Remix
  • Use official Cloudflare template
  • Configure server.ts for Workers
  • Access bindings via context.cloudflare.env
Astro
  • Use @astrojs/cloudflare adapter
  • Enable SSR in astro.config.mjs
  • Access env via Astro.locals.runtime.env
SvelteKit
  • Use @sveltejs/adapter-cloudflare
  • Configure in svelte.config.js
  • Access platform via event.platform.env

Resources

Implementation Checklist

Workers Setup
  • Install Wrangler CLI (npm install -g wrangler)
  • Login to Cloudflare (wrangler login)
  • Create project (wrangler init)
  • Configure wrangler.toml
  • Add environment variables/secrets
  • Test locally (wrangler dev)
  • Deploy (wrangler deploy)
Storage Setup (as needed)
  • Create D1 database and apply schema
  • Create KV namespace
  • Create R2 bucket
  • Configure Durable Objects
  • Set up Queues
  • Add bindings to wrangler.toml
Pages Setup
  • Connect Git repository or use CLI
  • Configure build settings
  • Set environment variables
  • Add Pages Functions (if needed)
  • Deploy and test
Production Checklist
  • Set up custom domain
  • Configure DNS records
  • Enable SSL/TLS
  • Set up monitoring/analytics
  • Configure rate limiting
  • Implement error handling
  • Set up CI/CD pipeline
  • Test gradual deployments
  • Document rollback procedure
  • Configure logging/observability

© einverne, MIT. Rendered from Markdown: HTML in the file is shown as text, images as links, and headings moved down two levels. Raw file

Files

Just SKILL.md in claude/skills/cloudflare of einverne/dotfiles.

Open the folder on GitHubat commit c6c0686

Compare with similar skills

Cloudflare next to the 5 skills that share the most tags, products or categories with it. Stars are the repository's; “used in” counts other GitHub owners with a copy.

Cloudflare compared with similar skills
SkillStarsUsed inTokensAuto-checkLicenceRepo updated
Cloudflare this skilleinverne/dotfiles121—~6.7kAutomated safety check: PassMIT
Durable Objectshodgef/apiker1274 repos~1.5kAutomated safety check: PassMIT
Apikerhodgef/apiker127—~1.4kAutomated safety check: PassMIT
Cloudflare WorkersEpicenterHQ/epicenter4.8k—~576Automated safety check: PassCustom licence
Cloudflareericrisco/rsc-harness167—~2.6kAutomated safety check: PassMIT
Cloudflare D1secondsky/claude-skills227—~3.9kAutomated safety check: PassMIT

Similar skills

  • Durable Objects

    hodgef/apiker

    Create and review Cloudflare Durable Objects. An agent skill from hodgef/apiker.

    127 GitHub starsUsed in 4 repos~1.5k tokens
    Backend & APIsAuto-check passed
  • Apiker

    hodgef/apiker

    Develop, review, and extend the Apiker library — a framework for building serverless REST APIs on Cloudflare Workers + Durable Objects.

    127 GitHub stars~1.4k tokensUpdated 1 mo ago
    Backend & APIsAuto-check passed
  • Cloudflare Workers

    EpicenterHQ/epicenter

    Cloudflare Workers patterns for Worker runtime APIs, Durable Objects, KV, R2, D1, Queues, WebSockets, streaming responses, bindings, wrangler configuration, and deployment limits.

    4.8k GitHub stars~576 tokensUpdated today
    Backend & APIsAuto-check passed
  • Cloudflare

    ericrisco/rsc-harness

    A skill your agent uses when working on Cloudflare's edge platform — wrangler.jsonc bindings, choosing between D1/KV/R2/Durable Objects/Queues, deploying a Worker or SPA via Static Assets, or…

    167 GitHub stars~2.6k tokensUpdated yesterday
    Backend & APIsAuto-check passed
  • Cloudflare D1

    secondsky/claude-skills

    Cloudflare D1 serverless SQLite on edge. An agent skill from secondsky/claude-skills.

    227 GitHub stars~3.9k tokensUpdated 10 days ago
    Backend & APIsAuto-check passed
  • Cloudflare Worker Dev

    curiositech/some_claude_skills

    Cloudflare Workers, KV, Durable Objects, and edge computing development.

    243 GitHub stars~3.4k tokensUpdated 1 mo ago
    Backend & APIsAuto-check: notes

More from einverne/dotfiles

All 39 skills in this repo
  • Chrome Devtools

    einverne/dotfiles

    Browser automation, debugging, and performance analysis using Puppeteer CLI scripts.

    121 GitHub starsUsed in 2 repos~1.6k tokens
    Auto-check: notes
  • DOCX

    einverne/dotfiles

    Comprehensive document creation, editing, and analysis with support for tracked changes, comments, formatting preservation, and text extraction.

    121 GitHub starsUsed in 35 repos~2.5k tokens
    Auto-check: notes
  • PDF

    einverne/dotfiles

    Comprehensive PDF manipulation toolkit for extracting text and tables, creating new PDFs, merging/splitting documents, and handling forms.

    121 GitHub starsUsed in 47 repos~1.8k tokens
    Auto-check passed
  • Gemini Audio

    einverne/dotfiles

    Guide for implementing Google Gemini API audio capabilities - analyze audio with transcription, summarization, and understanding (up to 9.5 hours), plus generate speech with controllable TTS.

    121 GitHub starsUsed in 1 repo~2k tokens
    Auto-check: notes
  • Gemini Image Gen

    einverne/dotfiles

    Guide for implementing Google Gemini API image generation - create high-quality images from text prompts using gemini-2.5-flash-image model.

    121 GitHub starsUsed in 1 repo~1.8k tokens
    Auto-check: notes
  • Gemini Vision

    einverne/dotfiles

    Guide for implementing Google Gemini API image understanding - analyze images with captioning, classification, visual QA, object detection, segmentation, and multi-image comparison.

    121 GitHub starsUsed in 1 repo~1.6k tokens
    Auto-check: notes

Categories

Questions about Cloudflare

What does Cloudflare do?

Guide for building applications on Cloudflare's edge platform. Cloudflare is an agent skill from einverne/dotfiles. Guide for building applications on Cloudflare's edge platform.

When should I use Cloudflare?

Cloudflare fits situations like: implementing serverless functions (Workers); edge databases (D1); real-time apps (Durable Objects); AI features (Workers AI.

How do I install Cloudflare in Claude Code?

Run `npx skills add einverne/dotfiles --skill cloudflare -a claude-code`. Or copy the skill folder (claude/skills/cloudflare in einverne/dotfiles) into .claude/skills/cloudflare in your project. Claude Code loads it when a task matches its description.

How do I install Cloudflare in Codex?

Run `npx skills add einverne/dotfiles --skill cloudflare -a codex`. Or copy the skill folder (claude/skills/cloudflare in einverne/dotfiles) into .agents/skills/cloudflare in your project. Codex loads it when a task matches its description.

Can I use Cloudflare in Cursor, Gemini CLI or GitHub Copilot?

Cursor, Gemini CLI, GitHub Copilot and OpenCode also load SKILL.md folders. With the skills CLI, run `npx skills add einverne/dotfiles --skill cloudflare -a cursor` (or -a gemini-cli, github-copilot or opencode for the others). To copy it by hand, put the folder in .cursor/skills/cloudflare, .gemini/skills/cloudflare, .github/skills/cloudflare and .opencode/skills/cloudflare in your project.

What does Cloudflare need to run?

Going by SKILL.md and its folder, Cloudflare needs the command-line tools its instructions call (wrangler, npm and npx) and credentials named JWT_SECRET and OPENAI_API_KEY. Our summary lists: Python 3; Node.js; A credential in OPENAI_API_KEY.

Does Cloudflare access the network?

SKILL.md names 5 domains. In commands or code: gateway.ai.cloudflare.com; the agent is likely to contact it when it follows the instructions. As links in the text: developers.cloudflare.com, discord.cloudflare.com, github.com and cloudflarestatus.com. This is read from the text; nothing was executed.

Is Cloudflare safe to install?

Our automated static check of SKILL.md found no risky patterns, such as piping downloads into a shell, reading credential files or hidden Unicode. It is not a guarantee. Review the folder before installing.

What licence does Cloudflare use?

Cloudflare is published under the MIT licence (declared in SKILL.md). It allows redistribution, so the full SKILL.md is shown on this page.

How many tokens does Cloudflare use?

About 6.7k tokens (SKILL.md is roughly 27k characters). Agents keep only the skill's name and description in context until a task matches; then they load SKILL.md in full.

What are the alternatives to Cloudflare?

Skills that share tags, products or a category with Cloudflare: Durable Objects (hodgef/apiker, 127 stars), Apiker (hodgef/apiker, 127 stars), Cloudflare Workers (EpicenterHQ/epicenter, 4.8k stars) and Cloudflare (ericrisco/rsc-harness, 167 stars). The comparison table on this page puts their stars, adoption, token cost, safety result and licence side by side.

Who maintains Cloudflare?

einverne (a GitHub user) maintains it in einverne/dotfiles, which has 121 GitHub stars. The repository holds 39 skills in this directory. The repository was last updated on September 9, 2026.

Source: einverne/dotfiles on GitHub. Facts on this page come from the repository at the commit we read; the author's words are quoted as theirs.