Loading source
Pulling the file list, source metadata, and syntax-aware rendering for this listing.
Source from repo
Comprehensive Cloudflare platform skill covering Workers, D1, R2, KV, AI, Durable Objects, and security.
Files
Skill
Size
Entrypoint
Format
Open file
Syntax-highlighted preview of this file as included in the skill package.
references/workerd/patterns.md
1# Workerd Patterns23## Multi-Service Architecture4```capnp5const config :Workerd.Config = (6services = [7(name = "frontend", worker = (8modules = [(name = "index.js", esModule = embed "frontend/index.js")],9compatibilityDate = "2024-01-15",10bindings = [(name = "API", service = "api")]11)),12(name = "api", worker = (13modules = [(name = "index.js", esModule = embed "api/index.js")],14compatibilityDate = "2024-01-15",15bindings = [(name = "DB", service = "postgres"), (name = "CACHE", kvNamespace = "kv")]16)),17(name = "postgres", external = (address = "db.internal:5432", http = ())),18(name = "kv", disk = (path = "/var/kv", writable = true))19],20sockets = [(name = "http", address = "*:8080", http = (), service = "frontend")]21);22```2324## Durable Objects25```capnp26const worker :Workerd.Worker = (27modules = [(name = "index.js", esModule = embed "index.js"), (name = "room.js", esModule = embed "room.js")],28compatibilityDate = "2024-01-15",29bindings = [(name = "ROOMS", durableObjectNamespace = "Room")],30durableObjectNamespaces = [(className = "Room", uniqueKey = "v1")],31durableObjectStorage = (localDisk = "/var/do")32);33```3435## Dev vs Prod Configs36```capnp37# Use parameter bindings for env-specific config38const baseWorker :Workerd.Worker = (39modules = [(name = "index.js", esModule = embed "src/index.js")],40compatibilityDate = "2024-01-15",41bindings = [(name = "API_URL", parameter = (type = text))]42);4344const prodWorker :Workerd.Worker = (45inherit = "base-service",46bindings = [(name = "API_URL", text = "https://api.prod.com")]47);48```4950## HTTP Reverse Proxy51```capnp52services = [53(name = "proxy", worker = (serviceWorkerScript = embed "proxy.js", compatibilityDate = "2024-01-15", bindings = [(name = "BACKEND", service = "backend")])),54(name = "backend", external = (address = "internal:8080", http = ()))55]56```5758## Local Development5960**Recommended:** Use Wrangler61```bash62wrangler dev # Uses workerd internally63```6465**Direct workerd:**66```bash67workerd serve config.capnp --socket-addr http=*:3000 --verbose68```6970**Environment variables:**71```capnp72bindings = [(name = "DATABASE_URL", fromEnvironment = "DATABASE_URL")]73```7475## Testing76```bash77workerd test config.capnp78workerd test config.capnp --test-only=test.js79```8081Test files must be included in `modules = [...]` config.8283## Production Deployment8485### Compiled Binary (Recommended)86```bash87workerd compile config.capnp myConfig -o production-server88./production-server89```9091### Docker92```dockerfile93FROM debian:bookworm-slim94RUN apt-get update && apt-get install -y ca-certificates95COPY workerd /usr/local/bin/96COPY config.capnp /etc/workerd/97COPY src/ /etc/workerd/src/98EXPOSE 808099CMD ["workerd", "serve", "/etc/workerd/config.capnp"]100```101102### Systemd103```ini104# /etc/systemd/system/workerd.service105[Service]106ExecStart=/usr/bin/workerd serve /etc/workerd/config.capnp --socket-fd http=3107Restart=always108User=nobody109```110111See systemd socket activation docs for complete setup.112113## Framework Integration114115### Hono116```javascript117import { Hono } from 'hono';118119const app = new Hono();120121app.get('/', (c) => c.text('Hello Hono!'));122app.get('/api/:id', async (c) => {123const id = c.req.param('id');124const data = await c.env.KV.get(id);125return c.json({ id, data });126});127128export default app;129```130131### itty-router132```javascript133import { Router } from 'itty-router';134135const router = Router();136137router.get('/', () => new Response('Hello itty!'));138router.get('/api/:id', async (request, env) => {139const { id } = request.params;140const data = await env.KV.get(id);141return Response.json({ id, data });142});143144export default {145fetch: (request, env, ctx) => router.handle(request, env, ctx)146};147```148149## Best Practices1501511. **Use ES modules** over service worker syntax1522. **Explicit bindings** - no global namespace assumptions1533. **Type safety** - define `Env` interfaces (use `wrangler types`)1544. **Service isolation** - split concerns into multiple services1555. **Pin compat date** in production after testing1566. **Use ctx.waitUntil()** for background tasks1577. **Handle errors gracefully** with try/catch1588. **Configure resource limits** on caches/storage159160## Common Patterns161162### Error Handling163```javascript164export default {165async fetch(request, env, ctx) {166try {167return await handleRequest(request, env);168} catch (error) {169console.error("Request failed", error);170return new Response("Internal Error", {status: 500});171}172}173};174```175176### Background Tasks177```javascript178export default {179async fetch(request, env, ctx) {180const response = new Response("OK");181182// Fire-and-forget background work183ctx.waitUntil(184env.ANALYTICS.put(request.url, Date.now())185);186187return response;188}189};190```191192See [configuration.md](./configuration.md) for config syntax, [api.md](./api.md) for runtime APIs, [gotchas.md](./gotchas.md) for common errors.193