Runtime

How to build a custom sandbox image from a list of packages

Call runtime.images.build({ name, recipe: { pip, apt, npm } }) once, then create each sandbox with image: name; the build is free.

On Runtime building an image costs nothing and uses no trial hours, and the free trial stores your first three images free for as long as you keep them. After that a stored image costs $0.08 per decimal GB per 30-day month on its whole file (rate in force since 23 September 2026, pricing). Every sandbox started from it has the packages already installed, instead of spending its first minute on pip install.

Build it and start from it

TypeScriptimport { Runtime } from "withruntime";const runtime = new Runtime();const image = await runtime.images.build(  { name: "data", recipe: { pip: ["pandas"], apt: ["jq"] } },  { onLog: (line) => console.log(line.text) },);await using sbx = await runtime.sandboxes.create({ image: "data" });console.log(  image.version,  (await sbx.exec("python3 -c 'import pandas; print(pandas.__version__)'")).stdout,);
Pythonfrom withruntime import Runtimeruntime = Runtime()image = runtime.images.build(name="data", recipe={"pip": ["pandas"], "apt": ["jq"]},                             on_log=lambda line: print(line["text"]))with runtime.sandboxes.create(image=image["id"]) as sbx:    print(sbx.exec("python3 -c 'import pandas; print(pandas.__version__)'").stdout)
Terminalimg=$(runtime image build --pip pandas --apt jq --name data)runtime sandbox create --image "${img}"

build streams the log, waits until the image is ready, and throws with the build's own error if a step fails. images.create queues the same build and returns at once, for a job that should not wait.

What a recipe takes

Field What it does
base runtime by default, Runtime's image with Python, Node and Bun; or any image
apt Ubuntu packages
pip Python packages
npm Node packages
commands Shell commands to run in the build
files Small files written into the image, 256 files and 1 MiB in all
env Environment variables set in the image
workdir The working directory

The CLI covers the common case with --pip, --apt and --npm; for commands, files or env, use an SDK or a Dockerfile.

Make it start a server too

An image can say what runs when a sandbox starts from it and when that sandbox counts as ready. The create then answers only once the server listens.

TypeScriptimport { Runtime } from "withruntime";const runtime = new Runtime();await runtime.images.build({  name: "api",  recipe: { pip: ["fastapi", "uvicorn"] },  start: { command: "uvicorn main:app --port 8000", readyPort: 8000, readyTimeoutSeconds: 60 },});const sbx = await runtime.sandboxes.create({ image: "api" });console.log(sbx.info.start); // { state: "ready", readyMs: ... }

start.state is ready, started (no ready check), timeout (the check did not pass within readyTimeoutSeconds, 60 by default, at most 300) or exited (the command ended first) (start and ready commands).

Recipes worth baking

  • R, Java or Go for the code interpreter. Otherwise each sandbox installs them the first time it uses them: about 35 seconds for Java or Go and 90 for R, measured on 23 September 2026. Put them in apt to skip that.
  • Docker. commands: ["enable-docker --no-start"] gives every sandbox Docker Engine, Buildx and Compose, started on the first docker command (Docker in a sandbox).
  • Your agent's tools. A coding agent's CLI, linters and test runners, so each task starts working at once (coding agent sandbox).

Limits

Limit Value
Builds at once 1 until the account has bought credit, then 4
Build machine 1 to 8 vCPUs (2 by default), 1 to 16 GiB of memory (4 GiB)
Scratch disk 1 to 32 GiB (4 GiB by default)
Build time 60 seconds to 1 hour (30 minutes by default)
Image size 512 MiB to 20 GiB (8 GiB by default)

The build runs in its own Firecracker virtual machine, with the same web access as a sandbox (limits).

Versions, tags and rebuilds

Each build of a name is its next version and takes the tag latest, or the tags you give. image on a create takes an id, name, name:tag or name@version, so production can pin data@3 while tests follow data.

A rebuild whose first steps match an earlier build of your account starts from the latest matching checkpoint, and an identical build is copied at once instead of built. Pass cache: false to build every step from scratch (faster rebuilds).

Mistakes to avoid

  • Installing packages in every sandbox. Each fresh sandbox then pays for the download and install in running time. Build once.
  • Passing both image and snapshot to a create. A sandbox starts from one or the other. A snapshot keeps a whole machine, memory included; an image keeps files.
  • Giving a recipe and a Dockerfile together. A build takes exactly one source: a recipe, an image or a dockerfile.
  • Forgetting old versions. Each stored image is charged; remove versions you no longer need with runtime image rm data@1.

Facts on this page were checked on 25 September 2026.