How Cloudflare Computer Runtime Types Work: A Complete Technical Guide
Cloudflare Computer runtime types are a pluggable TypeScript abstraction that defines how the workspace launches code execution, communicates over RPC, and manages sandboxed backends through a small set of contract types.
The Computer package provides a flexible execution environment where runtimes act as thin adapters between your workspace and various backends. The entire runtime type system lives in packages/computer/src/runtime/ and enables safe, sandboxed code execution with controlled I/O capabilities.
Core Runtime Types Explained
The runtime architecture centers on six key TypeScript types that establish contracts across the RPC boundary.
WorkspaceRuntime: The Main Controller
WorkspaceRuntime is the concrete class instantiated when you access workspace.runtime. Located in packages/computer/src/runtime/runtime.ts, it manages backend selection, tracks runtime IDs for sticky routing, and exposes the public API.
Key methods include:
exec()— launches a new executiongetExec()— retrieves an existing exec by IDkillExec()— terminates a running processdisposeExec()— cleans up resources
The class lazy-initializes on first use and maintains the runtimeId for session affinity.
RuntimeCall and RuntimeResult: The RPC Contract
In packages/computer/src/runtime/wire.ts, two types define the message format:
RuntimeCall — sent to the backend:
{
command: string; // code or command to execute
env?: Record<string, string>; // environment variables
runtimeId?: string; // for sticky routing to same container/worker
}
RuntimeResult — returned from the backend:
{
id: string; // exec identifier
status: 'pending' | 'running' | 'success' | 'error';
stdout: string;
stderr: string;
runtimeId: string; // identifies which backend instance ran this
}
These wire types keep the RPC layer agnostic to backend implementation details.
BridgeMessage: Low-Level Transport
BridgeMessage in packages/computer/src/runtime/bridge.ts wraps serialized RuntimeCall and RuntimeResult objects for Cap'n Proto transport. It carries capability handles across the boundary between the Durable Object and sandboxed runtime.
Capability and EgressConfig: Sandboxed I/O
Capability (packages/computer/src/runtime/capability.ts) represents host resources a runtime may request—WASM modules, KV bindings, D1 databases. The capability object passes through the RPC bridge so the runtime can invoke host-side resources safely.
EgressConfig (packages/computer/src/runtime/egress.ts) configures permitted outbound HTTP requests:
- Allowed URL patterns
- Permitted HTTP methods
- Request timeouts and limits
This dual system keeps runtimes sandboxed while enabling controlled external access.
How Runtime Types Work Together
The execution flow follows four stages:
-
Workspace initiates execution —
workspace.runtime.exec()creates aWorkspaceRuntimeinstance and serializes the call toRuntimeCall. -
Backend receives and spawns —
WorkspaceRuntimeroutes to the configured backend (worker-javascript, container-javascript, etc.) via the RPC bridge usingBridgeMessage. -
Execution and capture — The backend runs user code, streams stdout/stderr, and eventually returns a
RuntimeResult. -
Capability validation — Any resource requests or egress calls pass through
CapabilityandEgressConfigvalidation before reaching host services.
Practical Code Examples
Basic Execution with Default Runtime
import { Workspace } from '@cloudflare/computer';
// Create or connect to a workspace
const ws = await Workspace.create({
name: 'my-project',
backend: 'worker-javascript',
});
// Execute code — runtime created lazily on first use
const exec = await ws.runtime.exec(`console.log("Hello from Cloudflare Computer!")`);
// Wait for completion and read output
await exec.wait();
console.log(exec.stdout); // → Hello from Cloudflare Computer!
Sticky Runtime Sessions
// First exec creates a runtime and returns its ID
const first = await ws.runtime.exec(`node -e "console.log('instance A')"`);
console.log(first.runtimeId); // e.g., "wrkr-abc123"
// Force subsequent exec to same container/worker
const second = await ws.runtime.exec(
`node -e "console.log('still instance A')"`,
{ runtimeId: first.runtimeId }
);
Configuring Egress Policy
// Workspace-level egress configuration
const ws = await Workspace.create({
name: 'api-consumer',
egress: {
allowedUrls: ['https://api.example.com/*'],
allowedMethods: ['GET', 'POST'],
maxRequestDuration: 30000,
},
});
// Runtime fetch requests are validated against this policy
const exec = await ws.runtime.exec(`
fetch('https://api.example.com/data')
.then(r => r.json())
.then(data => console.log(JSON.stringify(data)))
`);
Source File Reference
| File | Purpose |
|---|---|
packages/computer/src/runtime/runtime.ts |
WorkspaceRuntime class — backend management and public API |
packages/computer/src/runtime/wire.ts |
RuntimeCall, RuntimeResult wire format types |
packages/computer/src/runtime/bridge.ts |
BridgeMessage and Cap'n Proto transport implementation |
packages/computer/src/runtime/capability.ts |
Capability type for host resource access |
packages/computer/src/runtime/egress.ts |
EgressConfig and outbound request validation |
packages/computer/tests/runtime.test.ts |
Unit tests covering runtime lifecycle and type contracts |
Extending the Runtime System
Adding a new backend requires only:
- Implementing the
RuntimeCall→RuntimeResultcontract - Wiring into
WorkspaceRuntimebackend selection - Handling
CapabilityandEgressConfigvalidation in your bridge implementation
All higher-level code—tests, examples, and the RPC layer—continues to work unchanged because the type contracts remain stable.
Summary
WorkspaceRuntimeinruntime.tsis the primary interface for creating and managing executionsRuntimeCallandRuntimeResultinwire.tsdefine the stable RPC contract between workspace and backendBridgeMessageinbridge.tshandles low-level Cap'n Proto transport with capability handlesCapabilityandEgressConfigenable sandboxed I/O with explicit host-controlled permissions- The minimal type surface makes backend extensions straightforward without breaking existing code
Frequently Asked Questions
What is a runtime ID in Cloudflare Computer?
A runtime ID is a string identifier returned in every RuntimeResult that uniquely identifies the backend instance (worker or container) that executed your code. Pass this ID to subsequent exec() calls using the runtimeId option to maintain session affinity—useful for preserving filesystem state or connection pools across multiple executions.
How does Cloudflare Computer keep runtimes secure?
Security operates at multiple layers: the capability system (capability.ts) requires explicit host grants for resources like KV or D1, while egress configuration (egress.ts) whitelists outbound URLs and methods. The RPC bridge validates all capability and egress requests before forwarding them, ensuring sandboxed code cannot access unapproved resources.
Can I use Cloudflare Computer runtime types with custom backends?
Yes. The runtime type system is deliberately backend-agnostic. Implement the RuntimeCall/RuntimeResult contract, wire your backend into WorkspaceRuntime's backend selection logic, and handle BridgeMessage transport. The existing test suite in tests/runtime.test.ts validates that new backends conform to expected type contracts.
Where are runtime results stored during execution?
RuntimeResult objects are not persisted to disk by default. The WorkspaceRuntime class holds exec state in memory and streams stdout/stderr through the active RPC connection. For result durability, your application code must capture and store the returned RuntimeResult or exec object before the workspace or Durable Object terminates.
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 →