--- id: personamanagmentlayer/pcl/cloudflare-expert version: "de4bb3ed" license: Apache-2.0 install: manual updated: 2026-03-30 --- # cloudflare-expert — Cloudflare Expert provides in-depth knowledge for building serverless applications on Cloudflare's edge platform. Learn to deploy code globally with Workers, optimize caching and CDN performance, implement security features like WAF and DDoS protection, and manage distributed state using Workers KV and Durable Objects. Publisher: personamanagmentlayer · Stars: 38 · Updated: 2026-03-30 Install (manual): `git clone https://github.com/personamanagmentlayer/pcl` ## SKILL.md # Cloudflare Expert Expert guidance for Cloudflare Workers, edge computing, CDN optimization, and Cloudflare security services. ## Core Concepts ### Cloudflare Services - Cloudflare Workers (serverless edge computing) - CDN and caching - DDoS protection - Web Application Firewall (WAF) - DNS management - Load balancing - Workers KV (key-value storage) - Durable Objects ### Edge Computing - Deploy code globally - Reduce latency - Process at the edge - Distributed state - Real-time applications ### Developer Tools - Wrangler CLI - Workers Playground - Edge APIs - Analytics and logs ## Cloudflare Workers ```javascript // Basic Worker export default { async fetch(request, env, ctx) { return new Response('Hello from Cloudflare Workers!', { headers: { 'Content-Type': 'text/plain' } }); } }; // Advanced routing export default { async fetch(request, env, ctx) { const url = new URL(request.url); // Route based on path switch (url.pathname) { case '/api/users': return handleUsers(request, env); case '/api/posts': return handlePosts(request, env); default: return new Response('Not Found', { status: 404 }); } } }; // API endpoint with JSON async function handleUsers(request, env) { if (request.method === 'GET') { const users = await env.USERS_KV.get('users', { type: 'json' }); return new Response(JSON.stringify(users), { headers: { 'Content-Type': 'application/json' } }); } if (request.method === 'POST') { const body = await request.json(); await env.USERS_KV.put('users', JSON.stringify(body)); return new Response('Created', { status: 201 }); } return new Response('Method Not Allowed', { status: 405 }); } ``` ## Workers KV Storage ```javascript // Workers KV operations export default { async fetch(request, env, ctx) { // Write await env.MY_KV.put('key', 'value'); // Write with metadata and expiration await env.MY_KV.put('key', 'value', { metadata: { userId: '123' }, expirationTtl: 3600 // 1 hour }); // Read const value = await env.MY_KV.get('key'); // Read as JSON const jsonValue = await env.MY_KV.get('key', { type: 'json' }); // Read with metadata const { value, metadata } = await env.MY_KV.getWithMetadata('key'); // Delete await env.MY_KV.delete('key'); // List keys const keys = await env.MY_KV.list({ prefix: 'user:' }); return new Response(JSON.stringify({ value, keys })); } }; // Caching pattern class CachedAPI { constructor(kv) { this.kv = kv; } async get(key, fetcher, ttl = 3600) { // Try cache first const cached = await this.kv.get(key, { type: 'json' }); if (cached) return cached; // Fetch and cache const data = await fetcher(); await this.kv.put(key, JSON.stringify(data), { expirationTtl: ttl }); return data; } } export default { async fetch(request, env, ctx) { const cache = new CachedAPI(env.MY_KV); const data = await cache.get('api:users', async () => { const response = await fetch('https://api.example.com/users'); return response.json(); }, 3600); return new Response(JSON.stringify(data)); } }; ``` ## Durable Objects ```javascript // Durable Object for stateful logic export class Counter { constructor(state, env) { this.state = state; this.value = 0; } async initialize() { this.value = await this.state.storage.get('value') || 0; } async fetch(request) { await this.initialize(); const url = new URL(request.url); if (url.pathname === '/increment') { this.value++; await this.state.storage.put('value', this.value); return new Response(String(this.value)); } if (url.pathname === '/decrement') { this.value--; await this.state.storage.put('value', this.value); return new Response(String(this.value)); } return new Response(String(this.value)); } } // WebSocket chat room with Durable Objects export class ChatRoom { constructor(state, env) { this.state = state; this.sessions = []; } async fetch(request) { if (request.headers.get('Upgrade') !== 'websocket') { return new Response('Expected WebSocket', { status: 426 }); } const pair = new WebSocketPair(); const [client, server] = Object.values(pair); await this.handleSession(server); return new Response(null, { status: 101, webSocket: client }); } async handleSession(websocket) { websocket.accept(); this.sessions.push(websocket); websocket.addEventListener('message', async (msg) => { // Broadcast to all sessions for (const session of this.sessions) { try { session.send(msg.data); } catch (err) { // Remove closed sessions this.sessions = this.sessions.filter(s => s !== session); } } }); } } // Worker that uses Durable Object export default { async fetch(request, env, ctx) { const url = new URL(request.url); const roomId = url.pathname.slice(1); // Get or create Durable Object const id = env.CHAT_ROOM.idFromName(roomId); const stub = env.CHAT_ROOM.get(id); return stub.fetch(request); } }; ``` ## Request/Response Handling ```javascript // CORS handling function handleCORS(request) { const corsHeaders = { 'Access-Control-Allow-Origin': '*', 'Access-Control-Allow-Methods': 'GET, POST, PUT, DELETE', 'Access-Control-Allow-Headers': 'Content-Type, Authorization' }; // Handle preflight if (request.method === 'OPTIONS') { return new Response(null, { headers: corsHeaders }); } return corsHeaders; } // Authentication middleware async function authenticate(request, env) { const token = request.headers.get('Authorization')?.replace('Bearer ', ''); if (!token) { return new Response('Unauthorized', { status: 401 }); } // Verify token (example using JWT) try { const payload = await verifyJWT(token, env.JWT_SECRET); return payload; } catch (err) { return new Response('Invalid token', { status: 401 }); } } // Rate limiting class RateLimiter { constructor(kv) { this.kv = kv; } async checkLimit(identifier, maxRequests, windowSeconds) { const key = `rate_limit:${identifier}`; const now = Date.now(); const windowMs = windowSeconds * 1000; // Get current count const data = await this.kv.get(key, { type: 'json' }); if (!data || now - data.timestamp > windowMs) { // New window await this.kv.put(key, JSON.stringify({ count: 1, timestamp: now }), { expirationTtl: windowSeconds }); return true; } if (data.count >= maxRequests) { return false; // Rate limit exceeded } // Increment count data.count++; await this.kv.put(key, JSON.stringify(data), { expirationTtl: windowSeconds }); return true; } } export default { async fetch(request, env, ctx) { const corsHeaders = handleCORS(request); if (request.method === 'OPTIONS') return corsHeaders; // Rate limiting const rateLimiter = new RateLimiter(env.RATE_LIMIT_KV); const clientIP = request.headers.get('CF-Connecting-IP'); const allowed = await rateLimiter.checkLimit(clientIP, 100, 60); if (!allowed) { return new Response('Rate limit exceeded', { status: 429, headers: corsHeaders }); } // Authentication const user = await authenticate(request, env); if (user instanceof Response) { return user; // Error response } // Process request const response = await handleRequest(request, env, user); // Add CORS headers to response Object.entries(corsHeaders).forEach(([key, value]) => { response.headers.set(key, value); }); return response; } }; ``` ## Caching Strategies ```javascript // Cache API async function cacheFirst(request) { const cache = caches.default; let response = await cache.match(request); if (!response) { response = await fetch(request); // Cache for 1 hour response = new Response(response.body, response); response.headers.set('Cache-Control', 'max-age=3600'); await cache.put(request, response.clone()); } return response; } // Stale-while-revalidate async function staleWhileRevalidate(request, ctx) { const cache = caches.default; let response = await cache.match(request); // Background refresh ctx.waitUntil( fetch(request).then(freshResponse => { const clonedResponse = freshResponse.clone(); cache.put(request, clonedResponse); }) ); if (response) { return response; } return fetch(request); } // Custom cache keys function customCacheKey(request) { const url = new URL(request.url); // Ignore query parameters for caching url.search = ''; // Add custom cache key based on headers const userAgent = request.headers.get('User-Agent'); const isMobile = /mobile/i.test(userAgent); url.searchParams.set('device', isMobile ? 'mobile' : 'desktop'); return new Request(url.toString(), request); } export default { async fetch(request, env, ctx) { const cacheKey = customCacheKey(request); if (request.url.includes('/api/')) { // API routes: stale-while-revalidate return staleWhileRevalidate(cacheKey, ctx); } // Static assets: cache first return cacheFirst(cacheKey); } }; ``` ## Edge Functions ```javascript // HTML rewriting export default { async fetch(request, env, ctx) { const response = await fetch(request); // Inject analytics script return new HTMLRewriter() .on('head', new HeadInjector()) .transform(response); } }; class HeadInjector { element(element) { element.append( '', { html: true } ); } } // Geolocation-based routing export default { async fetch(request, env, ctx) { const country = request.cf.country; // Route based on country const apiEndpoint = { 'US': 'https://us-api.example.com', 'EU': 'https://eu-api.example.com', 'default': 'https://global-api.example.com' }[country] || 'https://global-api.example.com'; const url = new URL(request.url); const apiUrl = new URL(url.pathname, apiEndpoint); return fetch(apiUrl, request); } }; // A/B testing export default { async fetch(request, env, ctx) { const url = new URL(request.url); // Determine variant let variant = request.headers.get('Cookie')?.match(/variant=(\w+)/)?.[1]; if (!variant) { variant = Math.random() < 0.5 ? 'A' : 'B'; } // Fetch appropriate version const response = await fetch(`${url.origin}/variant-${variant}${url.pathname}`); // Set cookie const newResponse = new Response(response.body, response); newResponse.headers.set('Set-Cookie', `variant=${variant}; Path=/; Max-Age=86400`); return newResponse; } }; ``` ## Wrangler CLI ```bash # Initialize project wrangler init my-worker # Development server wrangler dev # Deploy to production wrangler publish # Deploy to specific environment wrangler publish --env production # Tail logs wrangler tail # KV operations wrangler kv:namespace create "MY_KV" wrangler kv:key put --namespace-id= "key" "value" wrangler kv:key get --namespace-id= "key" # Durable Objects wrangler publish --new-class Counter # Secrets wrangler secret put SECRET_NAME ``` ## wrangler.toml Configuration ```toml name = "my-worker" main = "src/index.js" compatibility_date = "2024-01-01" # KV bindings kv_namespaces = [ { binding = "MY_KV", id = "xxxxxxxx" }, { binding = "CACHE_KV", id = "yyyyyyyy" } ] # Durable Objects [durable_objects] bindings = [ { name = "COUNTER", class_name = "Counter" }, { name = "CHAT_ROOM", class_name = "ChatRoom" } ] [[migrations]] tag = "v1" new_classes = ["Counter", "ChatRoom"] # Environment variables [vars] ENVIRONMENT = "production" # Routes routes = [ { pattern = "example.com/*", zone_name = "example.com" } ] # Cron triggers [triggers] crons = ["0 */6 * * *"] ``` ## Best Practices ### Performance - Cache aggressively at the edge - Minimize worker execution time - Use Workers KV for global data - Implement connection pooling - Optimize cache keys - Use stale-while-revalidate - Minimize external requests ### Security - Validate all inputs - Implement rate limiting - Use secrets for sensitive data - Set security headers - Implement CORS properly - Use HTTPS everywhere - Log security events ### Development - Use TypeScript for type safety - Test locally with wrangler dev - Implement proper error handling - Monitor worker metrics - Use environment variables - Version your workers - Document API endpoints ## Anti-Patterns ❌ Storing large data in KV frequently ❌ Long-running computations in workers ❌ Not implementing caching ❌ Hardcoding secrets ❌ Ignoring rate limits ❌ No error handling ❌ Excessive external API calls ## Resources - Cloudflare Workers: https://workers.cloudflare.com/ - Wrangler CLI: https://developers.cloudflare.com/workers/wrangler/ - Workers Examples: https://developers.cloudflare.com/workers/examples/ - Durable Objects: https://developers.cloudflare.com/workers/learning/using-durable-objects/ - Workers KV: https://developers.cloudflare.com/workers/runtime-apis/kv/ [View on SkillFed](https://skillfed.io/personamanagmentlayer/pcl/cloudflare-expert) · [View on GitHub](https://github.com/personamanagmentlayer/pcl)