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:
- Declarative images — build images with varying dependencies on demand when creating sandboxes
- 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:
- Hashes the image manifest to compute a cache key
- If cached, creates the sandbox from the existing checkpoint instantly
- 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.
| Method | Description |
|---|
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
| Field | Type | Description |
|---|
id | string | Unique snapshot identifier |
name | string | Snapshot name |
status | string | "building", "ready", or "failed" |
contentHash | string | SHA-256 hash of the image manifest |
checkpointId | string | Linked checkpoint ID |
manifest | object | The declarative image manifest |
createdAt | string | ISO 8601 creation timestamp |
lastUsedAt | string | ISO 8601 last usage timestamp |