# How to Expose the Unified Workspace API in Cloudflare Computer: A Complete Guide

> Learn to expose the unified Workspace API in Cloudflare Computer. Instantiate the Workspace class in a Durable Object, invoke ready(), and return workspace.stub() for filesystem, runtime, Git, and artifact operations.

- Repository: [Cloudflare/computer](https://github.com/cloudflare/computer)
- Tags: how-to-guide
- Published: 2026-09-04

---

**To expose the unified Workspace API in Cloudflare Computer, instantiate the `Workspace` class inside a Durable Object, optionally invoke `ready()` to materialize mounts, and return `workspace.stub()` to generate a `WorkspaceStub` that proxies filesystem, runtime, Git, and artifact operations across the Workers-RPC boundary.**

Cloudflare Computer bundles a host-side `Workspace` class that implements a complete filesystem, Git, artifact, and container execution runtime. To make this API available to Workers or other Durable Objects across the network boundary, you wrap the Workspace instance in a serializable stub rather than passing the heavy object directly. This guide walks through the implementation using the actual `cloudflare/computer` source code.

## Understanding the Workspace Architecture

The `Workspace` class defined in [`packages/computer/src/workspace.ts`](https://github.com/cloudflare/computer/blob/main/packages/computer/src/workspace.ts) provides the full host-side environment including storage backends, mount management, and execution contexts. Because this object contains stateful resources and internal capnweb transport that cannot cross the Workers-RPC boundary directly, Cloudflare Computer exposes it through the `WorkspaceStub` architecture found in [`packages/computer/src/stub.ts`](https://github.com/cloudflare/computer/blob/main/packages/computer/src/stub.ts).

The stub implements the same surface area as the local Workspace by forwarding operations through five specialized sub-stubs:

- **Filesystem** – `WorkspaceFilesystemStub` proxies `readFile`, `writeFile`, `stat`, `rm`, and other filesystem methods to `Workspace.fs`
- **Runtime** – `WorkspaceRuntimeStub` forwards container execution commands including `exec`, `getExec`, `killExec`, and `disposeExec`
- **Git** – `WorkspaceGitStub` exposes only the `cli` method as the canonical entry point for Git operations across RPC
- **Assets** – Stub for publishing and asset management APIs
- **Artifacts** – Stub for artifact retrieval and storage operations

Because the stub maintains identical method signatures to the local Workspace, callers use the same API regardless of whether they access the Workspace in-process or remotely.

## Step-by-Step Implementation

### Create the Workspace Instance

First, construct the `Workspace` with storage, backends, and optional mount configurations. The constructor accepts an object defining the Durable Object storage and execution backends.

```ts
import { Workspace } from "@cloudflare/computer";
import { CloudflareContainerBackend } from "@cloudflare/computer/backends/container";

export class MyDurableObject extends DurableObject {
  #ws = new Workspace({
    storage: this.ctx.storage,
    backends: [new CloudflareContainerBackend({ id: "container" })],
    // Optional: mounts, git configuration, asset handlers
  });
  
  // ... methods to expose the stub
}

```

The `Workspace` class exports the constructor and configuration interfaces through [`packages/computer/src/index.ts`](https://github.com/cloudflare/computer/blob/main/packages/computer/src/index.ts), which serves as the public entry point for the package.

### Materialize Mounts with ready()

Before exposing the Workspace to external callers, optionally invoke `await this.#ws.ready()` to ensure all configured mounts are indexed and filesystem metadata is loaded. This step prevents latency on the first filesystem operation but is not strictly required for the stub to function.

```ts
async getWorkspace() {
  await this.#ws.ready();  // Ensures mounts are materialized
  return this.#ws.stub();  // Returns the serializable stub
}

```

### Expose the WorkspaceStub

Return `workspace.stub()` from your Durable Object method to hand a `WorkspaceStub` across the RPC boundary. The stub extends `RpcTarget`, making it valid for Workers-RPC serialization.

```ts
async getWorkspace(): Promise<WorkspaceStub> {
  await this.#ws.ready();
  return this.#ws.stub();
}

```

Clients receiving this stub can interact with the full Workspace API as if they held a local instance, with all calls transparently forwarded to the host Durable Object.

## Consuming the API from Workers

On the client side—whether in a Worker, another Durable Object, or any Cloudflare runtime context—the returned stub implements the unified API. You interact with `ws.fs`, `ws.runtime`, and `ws.git` exactly as you would with a local Workspace instance.

```ts
async function demo(env: Env) {
  // Obtain the stub from the Durable Object
  const ws = await env.WORKSPACE_DO.get("instance-id").getWorkspace();

  // Filesystem operations proxy to Workspace.fs
  await ws.fs.writeFile("/hello.txt", "Cloudflare Computer");
  const content = await ws.fs.readFile("/hello.txt", "utf8");

  // Runtime execution in the configured container backend
  const handle = await ws.runtime.exec("ls -l /workspace");
  const { exitCode, stdout } = await handle.result();

  // Git operations via the CLI stub (the only cross-RPC entry point)
  const gitResult = await ws.git.cli({ 
    args: ["status"], 
    cwd: "/workspace" 
  });
}

```

The `WorkspaceFilesystemStub` forwards `readFile`, `writeFile`, and `stat` calls directly to the underlying `Workspace.fs` implementation. Similarly, `WorkspaceRuntimeStub` handles container lifecycle management, while `WorkspaceGitStub` restricts Git access to the `cli` method to maintain security boundaries across the RPC layer.

## Advanced RPC Server Composition

For scenarios requiring lower-level control or composition with other RPC contracts (such as `ShellRPC` or `SyncRPC`), use the server builders from [`packages/rpc/src/server.ts`](https://github.com/cloudflare/computer/blob/main/packages/rpc/src/server.ts) instead of the high-level stub.

```ts
import { createWorkspaceServer } from "@cloudflare/computer-rpc";
import { createSyncServer } from "@cloudflare/computer-rpc";
import { createShellServer } from "@cloudflare/computer-rpc";

// Inside your Durable Object:
const compositeRpc = createWorkspaceServer(db, runner);
// db = Workspace database instance
// runner = execution driver for container operations

```

These helpers construct the `WorkspaceRPC` contract defined in [`packages/rpc/src/interface.ts`](https://github.com/cloudflare/computer/blob/main/packages/rpc/src/interface.ts), allowing you to combine the Workspace API with additional RPC surfaces like `ShellRPC` for interactive shell sessions or `SyncRPC` for file synchronization protocols.

## Summary

- **Create** a `Workspace` instance in your Durable Object with storage and backend configurations from [`packages/computer/src/workspace.ts`](https://github.com/cloudflare/computer/blob/main/packages/computer/src/workspace.ts)
- **Initialize** the Workspace with `await workspace.ready()` to materialize mounts and cache filesystem metadata before serving requests
- **Expose** the unified API by returning `workspace.stub()`, which generates a `WorkspaceStub` from [`packages/computer/src/stub.ts`](https://github.com/cloudflare/computer/blob/main/packages/computer/src/stub.ts) that serializes across Workers-RPC
- **Consume** the identical API on the client side through `ws.fs`, `ws.runtime`, and `ws.git`, with all operations proxied to the host Durable Object
- **Compose** advanced RPC servers using `createWorkspaceServer` from [`packages/rpc/src/server.ts`](https://github.com/cloudflare/computer/blob/main/packages/rpc/src/server.ts) when combining Workspace functionality with other RPC contracts like `ShellRPC`

## Frequently Asked Questions

### What is the difference between Workspace and WorkspaceStub?

`Workspace` is the heavy host-side class instantiated in [`packages/computer/src/workspace.ts`](https://github.com/cloudflare/computer/blob/main/packages/computer/src/workspace.ts) that manages filesystem state, container runtimes, and Git operations. `WorkspaceStub` is a thin `RpcTarget` wrapper defined in [`packages/computer/src/stub.ts`](https://github.com/cloudflare/computer/blob/main/packages/computer/src/stub.ts) that forwards method calls across the Workers-RPC boundary. The stub exposes the same API surface but remains lightweight and serializable, whereas the Workspace contains internal transport mechanisms that cannot cross process boundaries.

### Why is Git access limited to the cli method across RPC?

The `WorkspaceGitStub` intentionally exposes only the `cli` method—accepting `args` and `cwd` parameters—rather than individual Git operations like `clone` or `commit`. This design consolidates all Git interactions through a single audited entry point in [`packages/computer/src/stub.ts`](https://github.com/cloudflare/computer/blob/main/packages/computer/src/stub.ts), reducing the attack surface for command injection while still enabling full Git functionality via argument arrays.

### When should I use createWorkspaceServer instead of workspace.stub()?

Use `createWorkspaceServer` from [`packages/rpc/src/server.ts`](https://github.com/cloudflare/computer/blob/main/packages/rpc/src/server.ts) when you need to combine the Workspace RPC with other RPC contracts such as `ShellRPC` or `SyncRPC`, or when you require custom RPC middleware. The `workspace.stub()` method provides the standard unified API sufficient for most filesystem and container operations, while the server builders offer granular control over RPC composition defined in [`packages/rpc/src/interface.ts`](https://github.com/cloudflare/computer/blob/main/packages/rpc/src/interface.ts).

### Do I need to call ready() before exposing the stub?

Calling `await workspace.ready()` is optional but recommended. This method ensures all configured mounts are indexed and backends are initialized before the first client request, preventing cold-start latency on initial filesystem operations. If omitted, the Workspace performs lazy initialization on the first access, which may introduce noticeable delay for complex mount configurations.