Files
2026-03-17 16:53:22 -07:00

4.8 KiB

Workerd APIs

Worker Code (JS/TS)

export default {
  async fetch(request, env, ctx) {
    const value = await env.KV.get("key");           // Bindings in env
    const response = await env.API.fetch(request);   // Service binding
    ctx.waitUntil(logRequest(request));              // Background task
    return new Response("OK");
  },
  async adminApi(request, env, ctx) { /* Named entrypoint */ },
  async queue(batch, env, ctx) { /* Queue consumer */ },
  async scheduled(event, env, ctx) { /* Cron handler */ }
};

TypeScript Types

Generate from wrangler.toml (Recommended):

wrangler types  # Output: worker-configuration.d.ts

Manual types:

interface Env {
  API: Fetcher;
  CACHE: KVNamespace;
  STORAGE: R2Bucket;
  ROOMS: DurableObjectNamespace;
  API_KEY: string;
}

export default {
  async fetch(request: Request, env: Env, ctx: ExecutionContext): Promise<Response> {
    return new Response(await env.CACHE.get("key"));
  }
};

Setup:

npm install -D @cloudflare/workers-types
// tsconfig.json
{"compilerOptions": {"types": ["@cloudflare/workers-types"]}}

Service Worker Syntax (Legacy)

addEventListener('fetch', event => {
  event.respondWith(handleRequest(event.request));
});

async function handleRequest(request) {
  const value = await KV.get("key");  // Bindings as globals
  return new Response("OK");
}

Durable Objects

export class Room {
  constructor(state, env) { this.state = state; this.env = env; }
  
  async fetch(request) {
    const url = new URL(request.url);
    if (url.pathname === "/increment") {
      const value = (await this.state.storage.get("counter")) || 0;
      await this.state.storage.put("counter", value + 1);
      return new Response(String(value + 1));
    }
    return new Response("Not found", {status: 404});
  }
}

RPC Between Services

// Caller: env.AUTH.validateToken(token) returns structured data
const user = await env.AUTH.validateToken(request.headers.get("Authorization"));

// Callee: export methods that return data
export default {
  async validateToken(token) { return {id: 123, name: "Alice"}; }
};

Web Platform APIs

Fetch

  • fetch(), Request, Response, Headers
  • AbortController, AbortSignal

Streams

  • ReadableStream, WritableStream, TransformStream
  • Byte streams, BYOB readers

Web Crypto

  • crypto.subtle (encrypt/decrypt/sign/verify)
  • crypto.randomUUID(), crypto.getRandomValues()

Encoding

  • TextEncoder, TextDecoder
  • atob(), btoa()

Web Standards

  • URL, URLSearchParams
  • Blob, File, FormData
  • WebSocket

Server-Sent Events (EventSource)

// Server-side SSE
const { readable, writable } = new TransformStream();
const writer = writable.getWriter();
writer.write(new TextEncoder().encode('data: Hello\n\n'));
return new Response(readable, {headers: {'Content-Type': 'text/event-stream'}});

HTMLRewriter (HTML Parsing/Transformation)

const response = await fetch('https://example.com');
return new HTMLRewriter()
  .on('a[href]', {
    element(el) {
      el.setAttribute('href', `/proxy?url=${encodeURIComponent(el.getAttribute('href'))}`);
    }
  })
  .on('script', { element(el) { el.remove(); } })
  .transform(response);

TCP Sockets (Experimental)

const socket = await connect({ hostname: 'example.com', port: 80 });
const writer = socket.writable.getWriter();
await writer.write(new TextEncoder().encode('GET / HTTP/1.1\r\n\r\n'));
const reader = socket.readable.getReader();
const { value } = await reader.read();
return new Response(value);

Performance

  • performance.now(), performance.timeOrigin
  • setTimeout(), setInterval(), queueMicrotask()

Console

  • console.log(), console.error(), console.warn()

Node.js Compat (nodejs_compat flag)

import { Buffer } from 'node:buffer';
import { randomBytes } from 'node:crypto';

const buf = Buffer.from('Hello');
const random = randomBytes(16);

Available: node:buffer, node:crypto, node:stream, node:util, node:events, node:assert, node:path, node:querystring, node:url NOT available: node:fs, node:http, node:net, node:child_process

CLI Commands

workerd serve config.capnp [constantName]          # Start server
workerd serve config.capnp --socket-addr http=*:3000 --verbose
workerd compile config.capnp constantName -o binary  # Compile to binary
workerd test config.capnp [--test-only=test.js]    # Run tests

Wrangler Integration

Use Wrangler for development:

wrangler dev     # Uses workerd internally
wrangler types   # Generate TypeScript types from wrangler.toml

See patterns.md for usage examples, configuration.md for config details.