Install any skill in seconds. Free to start, no credit card required.
Get Started Free →Build sandboxed applications for secure code execution. Load when building AI code execution, code interpreters, CI/CD systems, interactive dev environments, or executing untrusted code. Covers Sandbox SDK lifecycle, commands, files, code interpreter, and preview URLs. Biases towards retrieval from Cloudflare docs over pre-trained knowledge.
| Test case | Without → With | Effect | Δ tokens | Δ turns |
|---|---|---|---|---|
| case-01 | ✗→✓ | ▲ Improved | 42% | 0% |
| case-02 | ✗→✓ | ▲ Improved | 70% | 0% |
| case-03 | ✗→✓ | ▲ Improved | 2% | 0% |
| case-04 | ✗→✓ | ▲ Improved | -14% | 0% |
| case-05 | ✗→✓ | ▲ Improved | -14% | 0% |
Build secure, isolated code execution environments on Cloudflare Workers.
bashnpm install @cloudflare/sandbox docker info # Must succeed - Docker required for local dev
Your knowledge of the Sandbox SDK may be outdated. Prefer retrieval over pre-training for any Sandbox SDK task.
| Resource | URL | |----------|-----| | Docs | https://developers.cloudflare.com/sandbox/ | | API Reference | https://developers.cloudflare.com/sandbox/api/ | | Examples | https://github.com/cloudflare/sandbox-sdk/tree/main/examples | | Get Started | https://developers.cloudflare.com/sandbox/get-started/ |
When implementing features, fetch the relevant doc page or example first.
wrangler.jsonc (exact - do not modify structure):
jsonc{ "containers": [{ "class_name": "Sandbox", "image": "./Dockerfile", "instance_type": "lite", "max_instances": 1 }], "durable_objects": { "bindings": [{ "class_name": "Sandbox", "name": "Sandbox" }] }, "migrations": [{ "new_sqlite_classes": ["Sandbox"], "tag": "v1" }] }
Worker entry - must re-export Sandbox class:
typescriptimport { getSandbox } from '@cloudflare/sandbox'; export { Sandbox } from '@cloudflare/sandbox'; // Required export
| Task | Method | |------|--------| | Get sandbox | getSandbox(env.Sandbox, 'user-123') | | Run command | await sandbox.exec('python script.py') | | Run code (interpreter) | await sandbox.runCode(code, { language: 'python' }) | | Write file | await sandbox.writeFile('/workspace/app.py', content) | | Read file | await sandbox.readFile('/workspace/app.py') | | Create directory | await sandbox.mkdir('/workspace/src', { recursive: true }) | | List files | await sandbox.listFiles('/workspace') | | Expose port | await sandbox.exposePort(8080) | | Destroy | await sandbox.destroy() |
typescriptconst sandbox = getSandbox(env.Sandbox, 'user-123'); const result = await sandbox.exec('python --version'); // result: { stdout, stderr, exitCode, success }
Use runCode() for executing LLM-generated code with rich outputs:
typescriptconst ctx = await sandbox.createCodeContext({ language: 'python' }); await sandbox.runCode('import pandas as pd; data = [1,2,3]', { context: ctx }); const result = await sandbox.runCode('sum(data)', { context: ctx }); // result.results[0].text = "6"
Languages: python, javascript, typescript
State persists within context. Create explicit contexts for production.
typescriptawait sandbox.mkdir('/workspace/project', { recursive: true }); await sandbox.writeFile('/workspace/project/main.py', code); const file = await sandbox.readFile('/workspace/project/main.py'); const files = await sandbox.listFiles('/workspace/project');
| Need | Use | Why | |------|-----|-----| | Shell commands, scripts | exec() | Direct control, streaming | | LLM-generated code | runCode() | Rich outputs, state persistence | | Build/test pipelines | exec() | Exit codes, stderr capture | | Data analysis | runCode() | Charts, tables, pandas |
Base image (docker.io/cloudflare/sandbox:0.7.0) includes Python 3.11, Node.js 20, and common tools.
Add dependencies by extending the Dockerfile:
dockerfileFROM docker.io/cloudflare/sandbox:0.7.0 # Python packages RUN pip install requests beautifulsoup4 # Node packages (global) RUN npm install -g typescript # System packages RUN apt-get update && apt-get install -y ffmpeg && rm -rf /var/lib/apt/lists/* EXPOSE 8080 # Required for local dev port exposure
Keep images lean - affects cold start time.
Expose HTTP services running in sandboxes:
typescriptconst { url } = await sandbox.exposePort(8080); // Returns preview URL for the service
Production requirement: Preview URLs need a custom domain with wildcard DNS (*.yourdomain.com). The .workers.dev domain does not support preview URL subdomains.
See: https://developers.cloudflare.com/sandbox/guides/expose-services/
The SDK provides helpers for OpenAI Agents at @cloudflare/sandbox/openai:
typescriptimport { Shell, Editor } from '@cloudflare/sandbox/openai';
See examples/openai-agents for complete integration pattern.
getSandbox() returns immediately - container starts lazily on first operationsleepAfter)destroy() to immediately free resourcessandboxId always returns same sandbox instanceCommandClient, FileClient) - use sandbox.* methodsexport { Sandbox }destroy() for temporary sandboxesOther measured skills in the registry, with their headline benchmark lift.