Sandbox SDK — @next (1.0 preview)
Isolated Linux environments on Cloudflare Containers, driven from Workers.
Prefer preview docs and installed @next types over memory. APIs change; this skill is a gate, a contract, and a retrieval map—not a full manual.
We recommend new projects on this line. Apps still on the default package use sandbox-stable. Port only when asked, via sandbox-migrate-to-next.
1. Gate — confirm the package line
Before writing code, inspect the app:
| Check |
Must match |
| npm dependency |
@cloudflare/sandbox@next (or another preview tag) |
| Container image |
Same line (e.g. cloudflare/sandbox:next, next-python) |
| If you find… |
Action |
Default @cloudflare/sandbox (no @next) |
Stop. Load sandbox-stable. Do not apply this skill’s APIs. |
User wants to port stable → @next |
Stop. Load sandbox-migrate-to-next. |
| Self-deployed bridge only |
Bridge is not on the 1.0 preview line yet. Keep bridge on stable package + image. Bridge (stable) |
Never mix an @next Worker package with a stable container image (or the reverse).
Skills install: Agent setup · cloudflare/skills
2. Contract — non-negotiables
sandbox.exec(argv) takes an argv list and resolves when the process starts. It returns a handle, not a finished command result.
- Collect results with handle methods:
output(), logs(), waitForExit(), waitForPort(), waitForLog(), kill(signal?).
- No implicit shell. Shell syntax needs an explicit shell, e.g.
["/bin/bash", "-lc", script].
- Each launch is independent. A
cd / export in one exec is not visible to the next. Pass cwd and env per launch, or one shell script.
- Process handles have no stdin. Interactive use → terminals (
createTerminal + connect).
- Local wait
timeout / AbortSignal cancel the wait only. They do not kill the process. Use kill or exec’s remote timeout.
getProcess / listProcesses / getTerminal / listTerminals do not start a container; they return null / [] when none is up.
- Process and terminal IDs belong to the current container, not forever to a sandbox ID. For work that must survive replace, store the full job (argv, cwd, env, app state)—not only an id.
- Non-secret config only in
setEnvVars / launch env. Live credentials stay in the Worker; use outbound handlers when the sandbox calls external APIs.
- Do not invent removed stable APIs (
gitCheckout on core, string-exec completion, session execution, sandbox.terminal(request)).
- Do not use one retry loop for every error (see Errors docs).
Minimal shape:
import { getSandbox, proxyToSandbox, Sandbox } from "@cloudflare/sandbox";
export { Sandbox };
const sandbox = getSandbox(env.Sandbox, "user-123");
const process = await sandbox.exec(["python3", "-c", "print(2 + 2)"]);
const result = await process.output({ encoding: "utf8" });
// result.stdout, result.exitCode
Optional non-exhaustive cheatsheet (process/terminal/interpreter only): references/api-quick-ref.md
Examples index (next branch): references/examples.md
3. Retrieve — open the doc for the task
Fetch the page before implementing. Installed @next types win over guesses.
| You need to… |
Open |
| Orient / choose preview |
1.0 preview overview |
| First Worker, wrangler, Dockerfile |
Get started |
exec, handles, readiness, durability |
Process execution |
| Process API signatures |
Processes API |
| Sandbox ID vs container vs sleep/destroy |
Lifecycle |
cwd / env / setEnvVars |
Environment |
| Interactive PTY / browser terminal |
Terminals · Terminals API |
| Python/JS code interpreter |
Interpreter · Interpreter API |
| Extensions model |
Extensions |
| Error classes and recovery |
Errors · Errors API |
| Common failures |
Troubleshooting |
| API hub |
API reference |
Files, mounts, backups, ports, tunnels, proxyToSandbox |
Main docs for shared surfaces (ignore stable-only session/transport/sandbox.terminal): Files · Storage / mounts · Ports · Tunnels · Backups · Outbound traffic · Expose services · Production |
| Example apps |
examples on next |
| Still on stable package |
sandbox-stable · Main Sandbox docs |
| Porting an existing stable app |
sandbox-migrate-to-next · Migrate |
4. Before you ship
- Lockfile and Dockerfile on the same
@next line
- Typecheck against installed
@next types
- No live secrets in sandbox env
- Production preview hostnames need wildcard DNS on a custom domain when using those URL patterns
1---2name: sandbox-next3description: Use when building or changing Cloudflare Sandbox apps on @cloudflare/sandbox@next (Sandbox SDK 1.0 preview)—code execution, AI runners, interpreters, CI-like jobs, terminals, files, mounts, tunnels, preview URLs, lifecycle, or errors. Not for the default stable package (use sandbox-stable) or for porting stable to @next (use sandbox-migrate-to-next).4---5
6# Sandbox SDK — `@next` (1.0 preview)
7
8Isolated Linux environments on [Cloudflare Containers](https://developers.cloudflare.com/containers/), driven from Workers.
9
10**Prefer preview docs and installed `@next` types over memory.** APIs change; this skill is a gate, a contract, and a retrieval map—not a full manual.
11
12We recommend **new projects** on this line. Apps still on the default package use **`sandbox-stable`**. Port only when asked, via **`sandbox-migrate-to-next`**.
13
14## 1. Gate — confirm the package line
15
16Before writing code, inspect the app:
17
18| Check | Must match |
19| ----- | ---------- |
20| npm dependency | `@cloudflare/sandbox@next` (or another preview tag) |
21| Container image | Same line (e.g. `cloudflare/sandbox:next`, `next-python`) |
22
23| If you find… | Action |
24| ------------ | ------ |
25| Default `@cloudflare/sandbox` (no `@next`) | **Stop.** Load **`sandbox-stable`**. Do not apply this skill’s APIs. |
26| User wants to port stable → `@next` | **Stop.** Load **`sandbox-migrate-to-next`**. |
27| Self-deployed **bridge** only | Bridge is **not** on the 1.0 preview line yet. Keep bridge on stable package + image. [Bridge (stable)](https://developers.cloudflare.com/sandbox/bridge/) |
28
29Never mix an `@next` Worker package with a stable container image (or the reverse).
30
31Skills install: [Agent setup](https://developers.cloudflare.com/agent-setup/) · [cloudflare/skills](https://github.com/cloudflare/skills)
32
33## 2. Contract — non-negotiables
34
35- `sandbox.exec(argv)` takes an **argv** list and resolves when the process **starts**. It returns a **handle**, not a finished command result.
36- Collect results with handle methods: `output()`, `logs()`, `waitForExit()`, `waitForPort()`, `waitForLog()`, `kill(signal?)`.
37- No implicit shell. Shell syntax needs an explicit shell, e.g. `["/bin/bash", "-lc", script]`.
38- Each launch is independent. A `cd` / `export` in one `exec` is not visible to the next. Pass `cwd` and `env` per launch, or one shell script.
39- Process handles have **no stdin**. Interactive use → terminals (`createTerminal` + `connect`).
40- Local wait `timeout` / `AbortSignal` cancel the **wait only**. They do not kill the process. Use `kill` or `exec`’s remote `timeout`.
41- `getProcess` / `listProcesses` / `getTerminal` / `listTerminals` do **not** start a container; they return `null` / `[]` when none is up.
42- Process and terminal IDs belong to the **current container**, not forever to a sandbox ID. For work that must survive replace, store the full job (argv, cwd, env, app state)—not only an id.
43- Non-secret config only in `setEnvVars` / launch `env`. Live credentials stay in the Worker; use outbound handlers when the sandbox calls external APIs.
44- Do **not** invent removed stable APIs (`gitCheckout` on core, string-`exec` completion, session execution, `sandbox.terminal(request)`).
45- Do **not** use one retry loop for every error (see Errors docs).
46
47Minimal shape:
48
49```ts
50import { getSandbox, proxyToSandbox, Sandbox } from "@cloudflare/sandbox";
51
52export { Sandbox };
53
54const sandbox = getSandbox(env.Sandbox, "user-123");
55const process = await sandbox.exec(["python3", "-c", "print(2 + 2)"]);
56const result = await process.output({ encoding: "utf8" });
57// result.stdout, result.exitCode
58```
59
60Optional **non-exhaustive** cheatsheet (process/terminal/interpreter only): [references/api-quick-ref.md](references/api-quick-ref.md)
61Examples index (`next` branch): [references/examples.md](references/examples.md)
62
63## 3. Retrieve — open the doc for the task
64
65Fetch the page before implementing. Installed `@next` types win over guesses.
66
67| You need to… | Open |
68| ------------ | ---- |
69| Orient / choose preview | [1.0 preview overview](https://developers.cloudflare.com/sandbox/1-0-preview/) |
70| First Worker, wrangler, Dockerfile | [Get started](https://developers.cloudflare.com/sandbox/1-0-preview/get-started/) |
71| `exec`, handles, readiness, durability | [Process execution](https://developers.cloudflare.com/sandbox/1-0-preview/processes/) |
72| Process API signatures | [Processes API](https://developers.cloudflare.com/sandbox/1-0-preview/api/processes/) |
73| Sandbox ID vs container vs sleep/destroy | [Lifecycle](https://developers.cloudflare.com/sandbox/1-0-preview/lifecycle/) |
74| `cwd` / `env` / `setEnvVars` | [Environment](https://developers.cloudflare.com/sandbox/1-0-preview/environment/) |
75| Interactive PTY / browser terminal | [Terminals](https://developers.cloudflare.com/sandbox/1-0-preview/terminals/) · [Terminals API](https://developers.cloudflare.com/sandbox/1-0-preview/api/terminals/) |
76| Python/JS code interpreter | [Interpreter](https://developers.cloudflare.com/sandbox/1-0-preview/interpreter/) · [Interpreter API](https://developers.cloudflare.com/sandbox/1-0-preview/api/interpreter/) |
77| Extensions model | [Extensions](https://developers.cloudflare.com/sandbox/1-0-preview/extensions/) |
78| Error classes and recovery | [Errors](https://developers.cloudflare.com/sandbox/1-0-preview/errors/) · [Errors API](https://developers.cloudflare.com/sandbox/1-0-preview/api/errors/) |
79| Common failures | [Troubleshooting](https://developers.cloudflare.com/sandbox/1-0-preview/troubleshooting/) |
80| API hub | [API reference](https://developers.cloudflare.com/sandbox/1-0-preview/api/) |
81| Files, mounts, backups, ports, tunnels, `proxyToSandbox` | Main docs for shared surfaces (ignore stable-only session/transport/`sandbox.terminal`): [Files](https://developers.cloudflare.com/sandbox/api/files/) · [Storage / mounts](https://developers.cloudflare.com/sandbox/api/storage/) · [Ports](https://developers.cloudflare.com/sandbox/api/ports/) · [Tunnels](https://developers.cloudflare.com/sandbox/api/tunnels/) · [Backups](https://developers.cloudflare.com/sandbox/api/backups/) · [Outbound traffic](https://developers.cloudflare.com/sandbox/guides/outbound-traffic/) · [Expose services](https://developers.cloudflare.com/sandbox/guides/expose-services/) · [Production](https://developers.cloudflare.com/sandbox/guides/production-deployment/) |
82| Example apps | [examples on `next`](https://github.com/cloudflare/sandbox-sdk/tree/next/examples) |
83| Still on stable package | **`sandbox-stable`** · [Main Sandbox docs](https://developers.cloudflare.com/sandbox/) |
84| Porting an existing stable app | **`sandbox-migrate-to-next`** · [Migrate](https://developers.cloudflare.com/sandbox/1-0-preview/migrate/) |
85
86## 4. Before you ship
87
88- Lockfile and Dockerfile on the **same** `@next` line
89- Typecheck against installed `@next` types
90- No live secrets in sandbox env
91- Production preview hostnames need wildcard DNS on a custom domain when using those URL patterns