Skip to content
brought to you byVoidZero
Private Beta:Void is currently in Private Beta. We do not recommend using it for mission-critical production workloads yet. Please back up your data regularly.

Sandboxes

Void can wire Cloudflare Sandboxes into Void apps. A sandbox gives each session an isolated container for running commands, working with files, and exposing ports from server-side code.

ts
import { defineHandler } from 'void';
import { getSandbox } from 'void/sandbox';

export const POST = defineHandler(async (c) => {
  const { command } = await c.req.json<{ command: string }>();
  const sandbox = getSandbox('default');
  const result = await sandbox.exec(command);

  return c.json(result);
});

Importing from void/sandbox enables the SANDBOX Durable Object binding, exports the SDK's Sandbox class from the generated Worker entry, and adds the matching containers and migration metadata to the Cloudflare worker config.

Configuration

Most apps do not need config. The default binding is SANDBOX, the Durable Object class is Sandbox, local development uses the Dockerfile bundled with @cloudflare/sandbox, and void deploy uses the matching published sandbox image.

Use void.json when you need a custom image or container size:

json
{
  "sandbox": {
    "image": "./Dockerfile.sandbox",
    "platformImage": "registry.example.com/acme/sandbox:latest",
    "instanceType": "lite",
    "maxInstances": 2
  }
}

Available fields:

FieldDefaultDescription
bindingSANDBOXWorker binding name
classNameSandboxDurable Object class exported by the Worker
containerNamevoid-sandboxCloudflare container app name
imageBundled sandbox SDK DockerfileDockerfile path or registry image used by Wrangler/local
imageBuildContextDirectory of imageDocker build context for Wrangler/local
platformImageMatching sandbox SDK imageRegistry image used by void deploy
instanceTypelite on Void deployContainer size, such as lite, basic, standard-1
maxInstances20 on Void deployMaximum number of container instances

Runtime API

getSandbox(id, options) returns the SDK sandbox stub for a session id. IDs are normalized by default so user-provided session ids can safely map to Durable Object names.

ts
import { getSandbox } from 'void/sandbox';

const sandbox = getSandbox(`user-${user.id}`);
await sandbox.writeFile('/tmp/input.txt', 'hello');
const result = await sandbox.exec('cat /tmp/input.txt');

You can also use the namespace directly from c.env.SANDBOX when you need lower-level Durable Object control.

State persistence

There are two distinct layers to think about: stable Durable Object identity, and ephemeral container state.

getSandbox(id) always resolves to the same Durable Object instance for a given id, regardless of how many times the project has been deployed or rolled back. Anything written through the DO's persistent storage (ctx.storage, the embedded SQLite database) survives deploys, rollbacks, and container restarts. That layer is the durable home for sandbox metadata, session ids, and any data you need to outlive the container.

The container itself — filesystem, running processes, exposed ports, in-memory shell sessions — is tied to a single container lifetime and is not durable. Cloudflare Containers idle out after inactivity (the SDK default is sleepAfter: "10m"), and a container can also restart on a process crash or a platform-side reschedule. When that happens, files in the container filesystem, background processes, and previously exposed ports are lost. Setting keepAlive: true disables the idle timer but does not protect against crashes or infrastructure restarts.

Treat the sandbox container as a working environment, not a source of truth. Persist anything you cannot afford to lose to DO storage, your database, KV, or R2 (the SDK also offers backup/restore helpers for snapshotting a directory to R2). Project deletion destroys both layers, but plenty of routine events destroy only the container layer.

Deployment

void deploy provisions the SANDBOX Durable Object namespace, attaches the Cloudflare Container metadata to the Worker upload, and creates or updates the matching container application in the Void platform account.

Platform deploys require a registry image reference. The default sandbox works without extra config. If sandbox.image points at a custom local Dockerfile, also set sandbox.platformImage to an image you have already pushed to a registry.