Cloudflare Computer Backend Binding Requirements: Node.js Compat, Experimental Loaders, and Worker Configuration
The Cloudflare Computer library requires distinct binding configurations for each backend: Worker Shell and Worker JavaScript backends need a Worker Loader binding plus WorkspaceServiceProxy, the Container backend requires a Docker container binding and COMPUTERD namespace, and Node.js compatibility is enabled via runtime flags rather than additional bindings.
The cloudflare/computer repository provides multiple backend implementations for running compute workloads inside Cloudflare Workers. Each backend—Worker Shell, Worker JavaScript, and Container—has specific binding requirements that must be configured in your Durable Object environment to establish the RPC channel and dynamic worker instantiation.
Worker Shell Backend Requirements
The Worker Shell Backend (WorkerShellBackend) executes commands inside a dynamic Worker that lacks persistent storage. According to the source code in src/backends/worker-shell/worker-shell.ts, this backend requires three core bindings:
loader– A Worker Loader binding that exposes theget(name, getCode)API for creating dynamic workersworkspace– TheWorkspaceServiceProxyprops ({ props: WorkspaceServiceProxyProps }) used by the dynamic worker to call back into the host Durable Objectctx– The Durable Object state exposingexports.WorkspaceServiceProxythat provides the proxy implementation
Alternatively, you can provide a pre-constructed source object instead of the three individual bindings.
import { WorkerShellBackend } from "@cloudflare/computer/src/backends/worker-shell/index.js";
export class MyDO {
async fetch(request: Request, env: Env) {
const backend = new WorkerShellBackend({
loader: env.LOADER, // Worker-Loader binding
workspace: { props: { /* … */ } }, // WorkspaceServiceProxy props
ctx: env, // DO state
});
const handle = await backend.connect();
// Use handle.exec(), handle.dispose(), etc.
}
}
The WorkspaceServiceProxy defined in src/proxy.ts is essential because the dynamic worker must invoke the host's filesystem operations and sync methods through the HOST.getWorkspace() interface.
Worker JavaScript Backend Requirements (Experimental)
The Worker JavaScript Backend (WorkerJavaScriptBackend) relies on the experimental Workers-Loaders API to execute plain JavaScript inside a dynamic Worker. As implemented in [src/backends/worker-javascript/worker-javascript.ts`](https://github.com/cloudflare/computer/blob/main/src/backends/worker-javascript/worker-javascript.ts), it shares the same binding requirements as the Shell backend with one addition:
loader– The Worker Loader binding (experimental)workspace– IdenticalWorkspaceServiceProxyprops as the Shell backendctx– The Durable Object contextcompatibilityFlags– Optional array of flags (e.g.,"nodejs_compat")
import { WorkerJavaScriptBackend } from "@cloudflare/computer/src/backends/worker-javascript/index.js";
const backend = new WorkerJavaScriptBackend({
loader: env.LOADER, // Experimental Worker-Loader binding
workspace: { props: { /* … */ } }, // Same proxy requirements as Shell
ctx: env,
compatibilityFlags: ["nodejs_compat"] // Runtime flags
});
This backend is considered experimental because it relies on the dynamic worker-loader API, which is not yet generally available in all Cloudflare Workers environments.
Container Backend Requirements
The Container Backend (ContainerBackend) operates differently from the Worker-based backends. Instead of dynamic Workers, it runs the computerd shim inside a Docker container. The implementation in src/backends/container/index.ts requires:
container– A Docker-image binding specifying the container running thecomputerdbinarycomputerd– ADurableObjectNamespacebinding that the container uses to establish the Cap'n Proto RPC channel via@cloudflare/computer-rpc- Optional
artifacts,assets, andbindingsfor higher-level operations like publish and list commands
import { ContainerBackend } from "@cloudflare/computer/src/backends/container/index.js";
const backend = new ContainerBackend({
container: env.CONTAINER, // Docker image binding
computerd: env.COMPUTERD, // DurableObjectNamespace for RPC
// Optional: assets, artifacts, etc.
});
Unlike the Worker backends, the Container backend does not use the Worker Loader API. Instead, it relies on the COMPUTERD namespace binding to create the RPC bridge between the container and the host Durable Object.
Node.js Compatibility Configuration
Node.js compatibility is not a binding but a runtime configuration option. To enable Node-compatible globals (process, Buffer, etc.), add the "nodejs_compat" flag to the compatibilityFlags array when instantiating either the Worker Shell or Worker JavaScript backend.
const backend = new WorkerShellBackend({
loader: env.LOADER,
workspace: { props: { /* … */ } },
ctx: env,
compatibilityFlags: ["nodejs_compat"], // Just a flag, no binding required
});
The default compatibility flags are defined as DEFAULT_COMPAT_FLAGS in both src/backends/worker-shell/worker-shell.ts and src/backends/worker-javascript/worker-javascript.ts.
Summary
- Worker Shell Backend requires a
loaderbinding (Worker Loader API),workspaceprops (WorkspaceServiceProxy), andctx(Durable Object state) to spin up dynamic workers and proxy filesystem calls - Worker JavaScript Backend adds experimental loader support and accepts
compatibilityFlagsfor runtime features like Node.js compatibility - Container Backend replaces Worker Loader requirements with a
containerbinding (Docker image) andcomputerdnamespace binding for RPC communication - Node.js compatibility is enabled via the
"nodejs_compat"flag incompatibilityFlags, requiring no additional bindings
Frequently Asked Questions
What happens if I forget to provide the Worker Loader binding?
The constructors in src/backends/worker-shell/worker-shell.ts and src/backends/worker-javascript/worker-javascript.ts enforce these requirements at runtime. Without the loader binding, the backend cannot call get(name, getCode) to instantiate the dynamic worker, and initialization will fail before any commands can execute.
Can I use the same WorkspaceServiceProxy for multiple backend instances?
Yes. The WorkspaceServiceProxy defined in src/proxy.ts is designed to be shared across backend instances within the same Durable Object. Both Worker Shell and Worker JavaScript backends use identical proxy configurations to allow dynamic workers to call back into the host's HOST.getWorkspace() interface.
Why does the Container backend need a COMPUTERD binding instead of a Worker Loader?
The Container backend runs a Docker image with the computerd binary rather than a JavaScript Worker. It uses the Cap'n Proto RPC protocol defined in @cloudflare/computer-rpc to communicate with the host. The COMPUTERD binding provides the DurableObjectNamespace that the container uses to create an RPC stub back to the parent Durable Object, replacing the need for the dynamic Worker Loader API entirely.
Is the experimental Worker Loader API required for production use?
Currently, the Worker JavaScript backend requires the experimental Workers-Loaders API, which may not be available in all production environments. The Worker Shell backend also uses this API for dynamic worker creation. For production stability, the Container backend is often preferred because it relies only on standard Docker container bindings and Durable Object namespaces that are generally available.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →