Skip to main content
Workers are the core services in workerd that execute JavaScript and WebAssembly code. Each worker can be configured with code modules, bindings to external resources, and compatibility settings.

Basic worker structure

A worker definition includes the code to execute, compatibility settings, and optional bindings:
const myWorker :Workerd.Worker = (
  modules = [
    (name = "index.js", esModule = embed "index.js"),
  ],
  compatibilityDate = "2023-02-28",
  bindings = [
    (name = "API_KEY", text = "secret-value"),
  ],
);

Worker code formats

You can define worker code in three ways: Use the modules field to define one or more ES modules. The first module in the list is the main module that exports event handlers.
modules = [
  (name = "index.js", esModule = embed "index.js"),
  (name = "utils.js", esModule = embed "utils.js"),
  (name = "data.json", json = embed "data.json"),
  (name = "module.wasm", wasm = embed "module.wasm"),
],

Service Worker script

Use serviceWorkerScript for a single script that uses global addEventListener() to register event handlers:
serviceWorkerScript = embed "worker.js",

Inherited worker

Inherit from another worker to create a clone with modified settings:
inherit = "base-worker",
Derived workers can override:
  • bindings: Override specific named bindings (must match name and type in base)
  • globalOutbound: Override the outbound service
  • durableObjectStorage: Required if base defines Durable Object namespaces
  • durableObjectUniqueKeyModifier: Required for derived workers with Durable Objects

Module types

Each module in the modules list has a name and content:
name
Text
required
Module name or path used for imports. For example, "index.js" or "./utils/helpers.js".
esModule
Text
ES module with imports and exports. Use embed to include external files:
(name = "index.js", esModule = embed "index.js")
commonJsModule
Text
CommonJS module using require(). Use with namedExports to declare expected exports:
(name = "lib.js", commonJsModule = embed "lib.js", namedExports = ["foo", "bar"])
text
Text
Raw text blob. Importing produces a string:
(name = "template.html", text = embed "template.html")
data
Data
Raw binary data. Importing produces an ArrayBuffer:
(name = "data.bin", data = embed "data.bin")
wasm
Data
WebAssembly module. Importing produces a WebAssembly.Module object:
(name = "module.wasm", wasm = embed "module.wasm")
json
Text
JSON data. Importing produces the parsed JavaScript object:
(name = "config.json", json = embed "config.json")
pythonModule
Text
Python module. All bundles containing Python modules are converted to JS/WASM bundles prior to execution.
pythonRequirement
Text
Python package from Pyodide. The package is installed before worker execution. Value should be an empty string; only the module name matters.

Compatibility settings

workerd maintains backwards compatibility through compatibility dates and flags. Your code will always behave as it did on your specified date, even when workerd is updated.
compatibilityDate
Text
required
The date that determines which API behaviors your worker uses. Format: "YYYY-MM-DD".This must be specified unless the worker inherits from another worker.
compatibilityDate = "2023-02-28",
See Compatibility dates for available flags.
compatibilityFlags
List(Text)
Optional flags to enable specific features or behaviors:
compatibilityFlags = [
  "nodejs_compat",
  "streams_enable_constructors",
  "experimental",
],
Common flags:
  • "nodejs_compat": Enable Node.js compatibility APIs
  • "nodejs_compat_v2": Enhanced Node.js compatibility
  • "experimental": Enable experimental features
  • "no_global_navigator": Remove global navigator object
  • "streams_enable_constructors": Enable ReadableStream/WritableStream constructors

Outbound networking

globalOutbound
ServiceDesignator
default:"\"internet\""
Service that handles the global fetch() function. Defaults to the “internet” service.
globalOutbound = "custom-network",
cacheApiOutbound
ServiceDesignator
Service that handles Cache API requests (caches.default, caches.open()).

Durable Objects

Configure Durable Object namespaces for stateful, coordinated workers:
durableObjectNamespaces
List(DurableObjectNamespace)
List of Durable Object classes defined in this worker.
durableObjectNamespaces = [
  (className = "Counter", uniqueKey = "a1b2c3d4e5f6"),
  (className = "ChatRoom", uniqueKey = "f6e5d4c3b2a1"),
],

Durable Object namespace fields

className
Text
required
Exported class name that implements the Durable Object. Changing the class name doesn’t break compatibility with existing storage if uniqueKey stays the same.
uniqueKey
Text
Unique, stable ID for this namespace. Can be any string (GUID, random hex, etc.). This key:
  • Ensures objects have unique identifiers distinct from other classes
  • Is used for cryptographic derivation and validation of object IDs
  • Keeps IDs secret if you want to prevent forgery
Never lose this key, or you may not be able to recover stored data.
uniqueKey = "210bd0cbd803ef7883a1ee9d86cce06e",
ephemeralLocal
Void
Make instances ephemeral with no durable storage. The state.storage API is not present. These objects:
  • Allow arbitrary strings as IDs
  • Have no idFromName() or newUniqueId() methods
  • Are unique per-colo on Cloudflare’s network, not globally
Cloudflare Workers currently limits this feature to internal users only.
preventEviction
Bool
default:false
Keep Durable Objects pinned in memory forever. By default, objects are evicted after 10 seconds of inactivity.
This is only supported in workerd, not in production Durable Objects.
enableSql
Bool
default:false
Enable the storage.sql API for executing SQL queries. workerd uses SQLite to back all Durable Objects, but the SQL API is hidden by default.
container
ContainerOptions
Attach containers to Durable Objects in this namespace. workerd talks to the configured container engine to start containers based on the given image.
container = (
  imageName = "my-container-image",
),

Durable Object storage

durableObjectStorage
union
required
Specifies where Durable Objects are stored.
durableObjectStorage = (none = void),
  • none: Worker has no Durable Objects, or defines only ephemeralLocal namespaces
  • inMemory: Stores in-memory for the lifetime of the process (testing only)
  • localDisk: Stores in a local directory (experimental, subject to change)
durableObjectUniqueKeyModifier
Text
Additional text hashed with DurableObjectNamespace.uniqueKey. Required when using worker inheritance so each derived worker has unique Durable Object IDs.
Never lose this value, or you may not be able to recover stored data.

Tail workers

tails
List(ServiceDesignator)
List of tail worker services that receive tail events for this worker. See Tail Workers.
tails = ["logging-worker"],

Container engine

Configure container operations for Durable Objects with attached containers:
containerEngine = (none = void),

Complete example

using Workerd = import "/workerd/workerd.capnp";

const chatWorker :Workerd.Worker = (
  compatibilityDate = "2023-02-28",
  compatibilityFlags = ["nodejs_compat"],

  modules = [
    (name = "chat.js", esModule = embed "chat.js"),
    (name = "chat.html", text = embed "chat.html"),
    (name = "utils.js", esModule = embed "utils.js"),
  ],

  durableObjectNamespaces = [
    (className = "ChatRoom", uniqueKey = "210bd0cbd803ef7883a1ee9d86cce06e"),
    (className = "RateLimiter", uniqueKey = "b37b1c65c4291f3170033b0e9dd30ee1"),
  ],

  durableObjectStorage = (inMemory = void),

  bindings = [
    (name = "rooms", durableObjectNamespace = "ChatRoom"),
    (name = "limiters", durableObjectNamespace = "RateLimiter"),
    (name = "API_KEY", text = "secret-key"),
    (name = "backend", service = "backend-api"),
  ],

  globalOutbound = "internet",
);

Next steps

Bindings

Grant capabilities through bindings

Services

Learn about service types

Build docs developers (and LLMs) love