Templates
A template is the image a sandbox boots from. Impello ships a set of defaults, and you pick one by name when you create a sandbox.
Choose a template
Pass the name to Sandbox.create. With no name you get base.
import { Sandbox } from '@impello/sdk'
const sandbox = await Sandbox.create('codex')
const result = await sandbox.commands.run('codex --version')
console.log(result.stdout)
await sandbox.kill()Both SDKs read your key from IMPELLO_API_KEY; see
API keys. In TypeScript the name can also go in the options
object as template, and in Python as the template keyword argument.
The default templates
Every default ends as the user user with the working directory
/home/user, so a command you run lands there. codex, opencode, pi,
amp, droid, grok, openclaw and k3s start from base. claude,
code-interpreter, desktop and omarchy are built from their own image, so
they do not carry base's toolchain.
| Name | What it holds | vCPU | Memory |
|---|---|---|---|
base | Debian 12 with Python 3.12, Node 22, git, GitHub CLI, jq, ripgrep, curl, unzip, yarn, pnpm and build tools. The default. | 2 | 1 GB |
claude | Claude Code on Ubuntu 25.04, with Docker enabled at boot, Node 22, Python 3, pipx and uv. Binary at ~/.local/bin/claude. | 2 | 2 GB |
codex | base plus the Codex CLI, installed globally with npm. | 2 | 2 GB |
opencode | base plus the OpenCode CLI, installed globally with npm. | 2 | 2 GB |
pi | base plus the pi coding agent, installed globally with npm. | 2 | 2 GB |
amp | base plus the Amp CLI at ~/.local/bin/amp. | 2 | 2 GB |
droid | base plus the Droid CLI at ~/.local/bin/droid. | 2 | 2 GB |
grok | base plus the Grok CLI at ~/.grok/bin/grok. | 2 | 2 GB |
openclaw | base plus the OpenClaw CLI at ~/.npm-global/bin/openclaw. | 2 | 4 GB |
code-interpreter | Python 3.13 with Jupyter kernels for Python, R, JavaScript, Bash and Java. Jupyter starts with the sandbox. | 2 | 2 GB |
k3s | base plus single-node Kubernetes (k3s) and kubectl. The cluster starts at boot and KUBECONFIG is set. | 4 | 8 GB |
desktop | Ubuntu 22.04 with XFCE, Firefox, Chrome, VS Code, LibreOffice, x11vnc and noVNC. The GUI stack is installed but no start command is declared, so a sandbox from this template boots to a shell only. There is no supported way to start the desktop yet; use omarchy for a browser-reachable desktop. | 4 | 8 GB |
omarchy | Arch Linux with the Omarchy shell on a sway session, served over noVNC on port 6080. | 4 | 8 GB |
The CLIs installed with npm (codex, opencode, pi) are on the PATH. The
vendor installers put their binary under the home directory at the path shown,
and the template appends that directory to ~/.bashrc. commands.run runs
your command with bash -l -c. A login shell reads ~/.profile, not the end
of ~/.bashrc, so that appended line does not apply — call the binary by its
full path.
Aliases
Two templates answer to a second name. claude is also claude-code, and
code-interpreter is also code-interpreter-v1. Either name creates the same
sandbox.
Run an agent CLI
The base-derived agent templates (codex, opencode, pi, amp, droid,
grok, openclaw) are base plus one CLI; claude is its own Ubuntu image
with Docker, uv and pipx. In every one, nothing is signed in — pass the
vendor's key with envs when you create the sandbox. Those variables are set
for every command you run, and envs on a single command overrides them.
import { Sandbox } from '@impello/sdk'
const key = process.env.ANTHROPIC_API_KEY
if (!key) throw new Error('Set ANTHROPIC_API_KEY')
const sandbox = await Sandbox.create('claude', {
envs: { ANTHROPIC_API_KEY: key },
timeoutMs: 600_000,
})
const result = await sandbox.commands.run(
'~/.local/bin/claude -p "List the files in this directory"',
{ timeoutMs: 300_000 }
)
console.log(result.stdout)
await sandbox.kill()The pattern is the same for all of them: create by name, pass the vendor's key
in envs, run the binary. -p is Claude Code's print mode, which runs one
prompt and writes the answer to stdout; each vendor's CLI has its own flags, so
check the vendor's documentation. A command gives up after 60 seconds unless
you raise timeoutMs (timeout, in seconds, in Python); see
Run commands.
Reach a service in a template
Two templates declare a start command and wait for it before the sandbox is
ready: omarchy (noVNC on 6080) and code-interpreter (an HTTP server on
49999). k3s starts its cluster from a systemd unit instead, shortly after
boot. getHost(port) returns the host for a port; you supply the scheme and
the path.
The omarchy desktop is served at the path /vnc.html on port 6080.
import { Sandbox } from '@impello/sdk'
const sandbox = await Sandbox.create('omarchy', {
timeoutMs: 1_800_000,
})
console.log(`https://${sandbox.getHost(6080)}/vnc.html`)code-interpreter starts Jupyter with the sandbox and an HTTP server on port
49999 whose health check is /health. Neither SDK ships a client for that
server, so run code in this template with commands.run, for example
python3 -c "print(1 + 1)".
Sizes
Each template declares the vCPU count and memory it is built with, listed in
the table above. Your plan sets the largest sandbox you can run: Micro's
ceiling is 2 vCPU and 4 GB per sandbox, and Base and Scale are 4 vCPU and 8 GB.
k3s, desktop and omarchy are built at 4 vCPU and 8 GB, so they need Base
or Scale; the other ten fit inside Micro. See
Limits and pricing.
Updates
The defaults are rebuilt every week. The agent CLIs are installed unpinned, so
each rebuild picks up the vendor's current release and the version inside a
fresh sandbox moves with it. To freeze a version, build your own template from
a default with fromTemplate('claude') and create sandboxes from that name
instead.
Check that a name exists
Template.exists returns true when a name you own resolves. It lives in the
@impello/sdk/template subpath and is TypeScript only; the Python SDK has no
template module.
import { Template } from '@impello/sdk/template'
const exists = await Template.exists('my-app')
console.log(exists)
Build your own
When no default fits, start from one of them or from any Docker image and add what you need. The builder is TypeScript only, but the template it produces can be used from either SDK by name.
Next: Build a custom template.