Cloudflare Workers — SKILL.md
Raw skill file that agents receive when using this skill
---
name: "Cloudflare Workers"
description: "Skill for Cloudflare Workers — auto-generated from documentation"
version: "1.0.0"
author: "skynet"
category: "infrastructure"
agents: ["claude-code", "codex", "gemini"]
tags: ["cloudflare-workers", "infrastructure", "auto-generated"]
---
# Cloudflare Workers
---
name: Cloudflare Workers
description: Use this skill when building serverless applications, API endpoints, edge computing functions, or middleware that runs on Cloudflare's global network. Perfect for request routing, authentication, caching, A/B testing, and transforming HTTP requests/responses at the edge.
metadata:
author: skynet
version: 1.0.0
category: infrastructure
---
# Cloudflare Workers
## Setup and Authentication
### Install Wrangler CLI
```bash
npm install -g wrangler
# or
npm install wrangler --save-dev
```
### Authentication
```bash
# Login to Cloudflare
wrangler login
# Or use API token
wrangler config set cloudflare_api_token YOUR_API_TOKEN
# Verify authentication
wrangler whoami
```
## Project Initialization
### Create New Worker
```bash
# Create from template
wrangler generate my-worker
# Create from specific template
wrangler generate my-api worker-typescript
wrangler generate my-router worker-router
# Initialize in existing directory
wrangler init my-project
wrangler init my-project --type="webpack"
```
### Basic Worker Structure
```javascript
// src/index.js
export default {
async fetch(request, env, ctx) {
const url = new URL(request.url);
if (url.pathname === '/api/hello') {
return new Response('Hello World!', {
headers: { 'Content-Type': 'text/plain' }
});
}
return new Response('Not found', { status: 404 });
},
};
```
## Development Workflow
### Local Development
```bash
# Start dev server
wrangler dev
# Dev with specific port
wrangler dev --port 8080
# Dev with live reload
wrangler dev --live-reload
# Dev with specific compatibility date
wrangler dev --compatibility-date 2023-10-01
```
### Configuration (wrangler.toml)
```toml
name = "my-worker"
main = "src/index.js"
compatibility_date = "2023-10-01"
[env.production]
name = "my-worker-prod"
vars = { ENVIRONMENT = "production" }
[env.staging]
name = "my-worker-staging"
vars = { ENVIRONMENT = "staging" }
[[kv_namespaces]]
binding = "MY_KV"
id = "your-kv-namespace-id"
preview_id = "your-preview-kv-id"
```
## Deployment and Publishing
### Deploy Worker
```bash
# Deploy to production
wrangler publish
# Deploy to specific environment
wrangler publish --env staging
wrangler publish --env production
# Deploy with compatibility flags
wrangler publish --compatibility-flags nodejs_compat
```
### Manage Versions
```bash
# List deployments
wrangler deployments list
# Rollback to previous version
wrangler rollback --message "Rolling back due to issues"
# View deployment details
wrangler deployments view DEPLOYMENT_ID
```
## Common Worker Patterns
### API Route Handler
```javascript
export default {
async fetch(request, env) {
const url = new URL(request.url);
const path = url.pathname;
const method = request.method;
// CORS headers
const corsHeaders = {
'Access-Control-Allow-Origin': '*',
'Access-Control-Allow-Methods': 'GET, POST, PUT, DELETE',
'Access-Control-Allow-Headers': 'Content-Type',
};
if (method === 'OPTIONS') {
return new Response(null, { headers: corsHeaders });
}
try {
if (path === '/api/users' && method === 'GET') {
return handleGetUsers(env);
} else if (path === '/api/users' && method === 'POST') {
return handleCreateUser(request, env);
}
return new Response('Not found', { status: 404 });
} catch (error) {
return new Response(JSON.stringify({ error: error.message }), {
status: 500,
headers: { 'Content-Type': 'application/json', ...corsHeaders }
});
}
}
};
```
### Request Proxy with Modification
```javascript
export default {
async fetch(request, env) {
const url = new URL(request.url);
// Modify request headers
const modifiedRequest = new Request(request, {
headers: {
...request.headers,
'X-Custom-Header': 'Added by Worker',
'Authorization': env.API_KEY
}
});
// Proxy to origin
const response = await fetch(modifiedRequest);
// Modify response
const modifiedResponse = new Response(response.body, {
status: response.status,
statusText: response.statusText,
headers: {
...response.headers,
'X-Processed-By': 'Cloudflare Worker'
}
});
return modifiedResponse;
}
};
```
## KV Storage Operations
### Basic KV Usage
```javascript
export default {
async fetch(request, env) {
const url = new URL(request.url);
if (url.pathname === '/get') {
const value = await env.MY_KV.get('key');
return new Response(value || 'Not found');
}
if (url.pathname === '/set') {
await env.MY_KV.put('key', 'value', {
expirationTtl: 3600 // 1 hour
});
return new Response('Stored');
}
if (url.pathname === '/delete') {
await env.MY_KV.delete('key');
return new Response('Deleted');
}
}
};
```
### Manage KV Namespaces
```bash
# Create KV namespace
wrangler kv:namespace create "MY_NAMESPACE"
wrangler kv:namespace create "MY_NAMESPACE" --preview
# List KV pairs
wrangler kv:key list --namespace-id=your-namespace-id
# Put key-value
wrangler kv:key put --namespace-id=your-namespace-id "key" "value"
# Get value
wrangler kv:key get --namespace-id=your-namespace-id "key"
# Delete key
wrangler kv:key delete --namespace-id=your-namespace-id "key"
# Bulk upload
wrangler kv:bulk put --namespace-id=your-namespace-id data.json
```
## Environment Variables and Secrets
### Set Variables
```bash
# Set environment variable
wrangler secret put SECRET_KEY
# Set variable for specific environment
wrangler secret put SECRET_KEY --env production
# List secrets
wrangler secret list
wrangler secret list --env production
# Delete secret
wrangler secret delete SECRET_KEY
```
### Access in Worker
```javascript
export default {
async fetch(request, env) {
// Access environment variables
const apiKey = env.SECRET_KEY;
const dbUrl = env.DATABASE_URL;
return new Response(`Using API key: ${apiKey}`);
}
};
```
## Debugging and Monitoring
### View Logs
```bash
# Tail logs
wrangler tail
# Tail logs for specific environment
wrangler tail --env production
# Tail logs with filters
wrangler tail --status error
wrangler tail --method POST
wrangler tail --search "error"
```
### Analytics
```bash
# View analytics
wrangler analytics
# View analytics for date range
wrangler analytics --since 2023-01-01 --until 2023-01-31
```
## Decision Tree: Worker Use Cases
```
Need serverless function?
├── Simple API endpoint? → Basic Worker with fetch handler
├── Complex routing? → Use URLPattern or Router library
├── Database operations?
│ ├── Simple key-value? → Use KV storage
│ ├── SQL database? → Use D1 database binding
│ └── External API? → Use fetch with secrets
├── File processing? → Use Streams API
├── Authentication? → Implement JWT verification
└── Caching? → Use Cache API
```
## Troubleshooting
### Common Errors and Solutions
**Error**: `Error: No account found`
```bash
# Solution: Login again
wrangler login
# or check API token
wrangler whoami
```
**Error**: `Error: Unable to find the Worker script associated with this deployment`
```bash
# Solution: Ensure correct environment
wrangler publish --env production
# or check wrangler.toml configuration
```
**Error**: `Error: KV namespace not found`
```bash
# Solution: Create namespace and update wrangler.toml
wrangler kv:namespace create "MY_NAMESPACE"
# Add namespace ID to wrangler.toml
```
**Error**: `Error: Worker exceeded memory limit`
```javascript
// Solution: Optimize memory usage
export default {
async fetch(request, env, ctx) {
// Use streaming for large responses
const { readable, writable } = new TransformStream();
ctx.waitUntil(
processLargeData(writable)
);
return new Response(readable);
}
};
```
**Error**: `Error: Worker exceeded CPU time limit`
```javascript
// Solution: Use ctx.waitUntil for non-blocking operations
export default {
async fetch(request, env, ctx) {
// Quick response
const response = new Response('Processing...');
// Long-running task
ctx.waitUntil(
processInBackground(request, env)
);
return response;
}
};
```
**Error**: `TypeError: env.MY_KV is undefined`
```toml
# Solution: Add KV binding to wrangler.toml
[[kv_namespaces]]
binding = "MY_KV"
id = "your-namespace-id"
```
### Debug Tips
```javascript
// Add logging for debugging
export default {
async fetch(request, env, ctx) {
console.log('Request URL:', request.url);
console.log('Request method:', request.method);
console.log('Request headers:', Object.fromEntries(request.headers));
try {
// Your logic here
return new Response('Success');
} catch (error) {
console.error('Worker error:', error);
return new Response('Error', { status: 500 });
}
}
};
```
curl -s https://skills.skynet.ceo/api/skills/cloudflare-workers/skill.md