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 the get(name, getCode) API for creating dynamic workers
  • workspace – The WorkspaceServiceProxy props ({ props: WorkspaceServiceProxyProps }) used by the dynamic worker to call back into the host Durable Object
  • ctx – The Durable Object state exposing exports.WorkspaceServiceProxy that 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 – Identical WorkspaceServiceProxy props as the Shell backend
  • ctx – The Durable Object context
  • compatibilityFlags – 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 the computerd binary
  • computerd – A DurableObjectNamespace binding that the container uses to establish the Cap'n Proto RPC channel via @cloudflare/computer-rpc
  • Optional artifacts, assets, and bindings for 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 loader binding (Worker Loader API), workspace props (WorkspaceServiceProxy), and ctx (Durable Object state) to spin up dynamic workers and proxy filesystem calls
  • Worker JavaScript Backend adds experimental loader support and accepts compatibilityFlags for runtime features like Node.js compatibility
  • Container Backend replaces Worker Loader requirements with a container binding (Docker image) and computerd namespace binding for RPC communication
  • Node.js compatibility is enabled via the "nodejs_compat" flag in compatibilityFlags, 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:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →