Skip to main content
Templates are an alpha, experimental feature. APIs, behavior, and manifest formats may change without notice.
Templates provide a code-first approach to defining sandbox environments. Instead of configuring images manually, you define them programmatically using the SDK. The system supports two workflows:
  1. Declarative images — build images with varying dependencies on demand when creating sandboxes
  2. Pre-built snapshots — create and register ready-to-use snapshots that can be shared across multiple sandboxes

Declarative image building

Build images on-the-fly when creating sandboxes. Ideal for iterating quickly without creating separate snapshots. Declarative images are cached by content hash — identical manifests produce the same image. Subsequent runs reuse the cached image instantly.
import { Sandbox } from '@opencomputer/sdk';
import { Image } from '@opencomputer/sdk/node';

// Define an image with packages, env vars, and files
const image = Image.base()
  .aptInstall(['curl', 'jq'])
  .pipInstall(['requests', 'pandas'])
  .env({ PROJECT_ROOT: '/workspace' })
  .workdir('/workspace');

// Create a sandbox — the image is built on first run, cached after
const sandbox = await Sandbox.create({
  image,
  timeout: 300,
  onBuildLog: (log) => console.log(`build: ${log}`),
});

const result = await sandbox.exec.run('which curl');
console.log(result.exitCode); // 0
When you pass an image to Sandbox.create(), the server:
  1. Hashes the image manifest to compute a cache key
  2. If cached, creates the sandbox from the existing checkpoint instantly
  3. If not cached, boots a build sandbox, executes each step, checkpoints the result, then creates your sandbox from it

Build memory

Images build in a 4 GB sandbox by default. If a build runs out of memory (heavy apt/pip/npm, compiling a large toolchain), raise the build-phase RAM with .builderMemory(mb) / .builder_memory(mb). This only affects the build. The resulting image is unchanged — you size the actual sandbox when you create it, via memoryMB:
// 8 GB to build…
const image = Image.base()
  .aptInstall(['build-essential', 'cmake'])
  .runCommands('make -j')
  .builderMemory(8192);

// …but the sandbox runs at whatever you ask for
const sandbox = await Sandbox.create({ image, memoryMB: 4096 });
builderMemory doesn’t change the cache key — it’s a build resource, not image content.

Creating pre-built snapshots

Create named snapshots that persist permanently and can be shared across sandboxes. Snapshots are visible in the dashboard and don’t need to be rebuilt.
import { Image, Snapshots } from '@opencomputer/sdk/node';

const snapshots = new Snapshots();

// Define the image
const image = Image.base()
  .aptInstall(['python3-pip'])
  .pipInstall(['pandas', 'numpy', 'scikit-learn'])
  .workdir('/workspace');

// Create a named snapshot with build log streaming
await snapshots.create({
  name: 'data-science',
  image,
  onBuildLogs: (log) => console.log(`build: ${log}`),
});

// Now create sandboxes from the snapshot — instant, no build step
const sandbox = await Sandbox.create({ snapshot: 'data-science' });

Sizing a fork’s memory

A sandbox created from a snapshot inherits the snapshot’s memory by default. Pass memoryMB to give it more RAM — useful when one branch needs more headroom than the base.
// Fork the snapshot with 8 GB instead of its captured size
const sandbox = await Sandbox.create({ snapshot: 'data-science', memoryMB: 8192 });
memoryMB is clamped to a valid range, and the response’s memoryMB reports the effective value:
  • Floor — the snapshot’s own memory. A smaller request is ignored; a fork can’t start smaller than the snapshot it restores. A 4 GB snapshot forked with memoryMB: 1024 still boots at ~4 GB.
  • Ceiling. Larger requests are capped to the maximum platform tier.
The same memoryMB field works when forking from a checkpoint.

Managing snapshots

const snapshots = new Snapshots();

// List all snapshots
const list = await snapshots.list();
for (const s of list) {
  console.log(`${s.name}${s.status}`);
}

// Get a specific snapshot
const snapshot = await snapshots.get('data-science');
console.log(snapshot.status); // "ready"

// Delete a snapshot
await snapshots.delete('data-science');

Default template

Sandboxes use the default template when no image or snapshot is specified. It includes:
  • Ubuntu 22.04
  • Python 3 with pip, venv, setuptools
  • Node.js 20 LTS with npm
  • Build tools: build-essential, cmake, pkg-config
  • CLI tools: git, git-lfs, curl, wget, jq, rsync, htop, tree
  • Editors: nano, vim-tiny
  • Database: sqlite3
  • Networking: openssh-client, iproute2, net-tools, dnsutils
  • Claude Agent SDK and claude-code (pre-installed for agent sessions)

Image configuration

The Image class provides a fluent, immutable API for defining sandbox environments. Each method returns a new Image instance — the original is never modified.
MethodDescription
Image.base()Start from the default OpenSandbox environment
.aptInstall(packages) / .apt_install(packages)Install system packages via apt-get
.pipInstall(packages) / .pip_install(packages)Install Python packages via pip
.runCommands(...cmds) / .run_commands(*cmds)Run shell commands during build
.env(vars)Set environment variables (written to /etc/environment)
.workdir(path)Set default working directory
.addFile(path, content) / .add_file(path, content)Embed a file with inline content
.addLocalFile(local, remote) / .add_local_file(local, remote)Read a local file into the image
.addLocalDir(local, remote) / .add_local_dir(local, remote)Read a local directory into the image
.builderMemory(mb) / .builder_memory(mb)RAM for the build phase (default 4 GB; doesn’t affect the resulting sandbox)
.toJSON() / .to_dict()Return the image manifest
.cacheKey() / .cache_key()Compute SHA-256 content hash

SnapshotInfo

FieldTypeDescription
idstringUnique snapshot identifier
namestringSnapshot name
statusstring"building", "ready", or "failed"
contentHashstringSHA-256 hash of the image manifest
checkpointIdstringLinked checkpoint ID
manifestobjectThe declarative image manifest
createdAtstringISO 8601 creation timestamp
lastUsedAtstringISO 8601 last usage timestamp
Full SDK reference: TypeScript SDK · Python SDK · HTTP API.