Run sandboxed code environments on Cloudflare's edge network
1,128
stars
771
commits
TypeScript
primary language
Sep 10, 2026
updated
Build secure, isolated code execution environments on Cloudflare.
The Sandbox SDK lets you run untrusted code safely in isolated containers. Execute commands, manage files, run background processes, and expose services — all from your Workers applications.
Perfect for AI code execution, interactive development environments, data analysis platforms, CI/CD systems, and any application that needs secure code execution at the edge.
Create a new Sandbox SDK project using the minimal template:
npm create cloudflare@latest -- my-sandbox --template=cloudflare/sandbox-sdk/examples/minimal
cd my-sandbox
Start the development server:
npm run dev
Note: First run builds the Docker container (2-3 minutes). Subsequent runs are much faster.
Test the endpoints:
# Execute Python code
curl http://localhost:8787/run
# File operations
curl http://localhost:8787/file
Deploy your Worker and container:
npx wrangler deploy
Wait for provisioning: After first deployment, wait 2-3 minutes before making requests.
📖 View the complete getting started guide for detailed instructions and explanations.
import { getSandbox, proxyToSandbox, type Sandbox } from '@cloudflare/sandbox';
export { Sandbox } from '@cloudflare/sandbox';
type Env = {
Sandbox: DurableObjectNamespace<Sandbox>;
};
export default {
async fetch(request: Request, env: Env): Promise<Response> {
// Required for preview URLs
const proxyResponse = await proxyToSandbox(request, env);
if (proxyResponse) return proxyResponse;
const url = new URL(request.url);
const sandbox = getSandbox(env.Sandbox, 'my-sandbox');
// Execute Python code
if (url.pathname === '/run') {
const result = await sandbox.exec('python3 -c "print(2 + 2)"');
return Response.json({ output: result.stdout, success: result.success });
}
// Work with files
if (url.pathname === '/file') {
await sandbox.writeFile('/workspace/hello.txt', 'Hello, Sandbox!');
const file = await sandbox.readFile('/workspace/hello.txt');
return Response.json({ content: file.content });
}
return new Response('Try /run or /file');
}
};
Pass options as the third argument to getSandbox() to configure sandbox
lifetime and container startup metadata:
const sandbox = getSandbox(env.Sandbox, 'tenant-workspace', {
sleepAfter: '30m',
labels: {
tenantId: 'tenant_123',
workload: 'code-workspace'
}
});
Container labels are attached to the underlying Cloudflare Container for analytics and observability. Labels are applied when the container starts; if labels are changed while a container is already running, the new labels apply the next time the container starts.
sandbox.tunnels.get(port) exposes a service running inside the
sandbox on a *.trycloudflare.com URL. No Cloudflare account or DNS
setup required — cloudflared opens a persistent QUIC connection to
Cloudflare's edge and Cloudflare hands back a hostname.
// Inside a Worker with an RPC-transport sandbox:
const tunnel = await sandbox.tunnels.get(8080);
console.log(tunnel.url);
// → https://random-words-here.trycloudflare.com
// Repeated calls for the same port return the same record:
const same = await sandbox.tunnels.get(8080);
console.log(same.url === tunnel.url); // true
// Tear down by port number or by the record:
await sandbox.tunnels.destroy(8080);
// or: await sandbox.tunnels.destroy(tunnel);
get() is idempotent: it consults a per-sandbox cache in Durable
Object storage, returns the cached record on a hit, and only spawns a
fresh cloudflared process on a miss. list() returns every cached
tunnel.
Notes:
tunnels
stub throws "RPC transport required".get(port) after a restart returns a fresh record.get() resolves.*.trycloudflare.com buffers text/event-stream responses.
WebSockets work fine.*.trycloudflare.com URLs via sandbox.tunnels.get(port)We welcome contributions from the community! See CONTRIBUTING.md for guidelines on:
This repository contains the SDK source code. Quick start:
# Clone the repo
git clone https://github.com/cloudflare/sandbox-sdk
cd sandbox-sdk
# Install dependencies
npm install
# Run tests
npm test
# Build the project
npm run build
# Type checking and linting
npm run check
See the examples directory for complete working examples:
Shell and Editor tools for OpenAI Agents SDKBeta - The SDK is in active development. APIs may change before v1.0.
(top 30 of 39)
TypeScript
97.1%
Python
1.6%
Run sandboxed code environments on Cloudflare's edge network
1,128
stars
771
commits
TypeScript
primary language
Sep 10, 2026
updated
Build secure, isolated code execution environments on Cloudflare.
The Sandbox SDK lets you run untrusted code safely in isolated containers. Execute commands, manage files, run background processes, and expose services — all from your Workers applications.
Perfect for AI code execution, interactive development environments, data analysis platforms, CI/CD systems, and any application that needs secure code execution at the edge.
Create a new Sandbox SDK project using the minimal template:
npm create cloudflare@latest -- my-sandbox --template=cloudflare/sandbox-sdk/examples/minimal
cd my-sandbox
Start the development server:
npm run dev
Note: First run builds the Docker container (2-3 minutes). Subsequent runs are much faster.
Test the endpoints:
# Execute Python code
curl http://localhost:8787/run
# File operations
curl http://localhost:8787/file
Deploy your Worker and container:
npx wrangler deploy
Wait for provisioning: After first deployment, wait 2-3 minutes before making requests.
📖 View the complete getting started guide for detailed instructions and explanations.
import { getSandbox, proxyToSandbox, type Sandbox } from '@cloudflare/sandbox';
export { Sandbox } from '@cloudflare/sandbox';
type Env = {
Sandbox: DurableObjectNamespace<Sandbox>;
};
export default {
async fetch(request: Request, env: Env): Promise<Response> {
// Required for preview URLs
const proxyResponse = await proxyToSandbox(request, env);
if (proxyResponse) return proxyResponse;
const url = new URL(request.url);
const sandbox = getSandbox(env.Sandbox, 'my-sandbox');
// Execute Python code
if (url.pathname === '/run') {
const result = await sandbox.exec('python3 -c "print(2 + 2)"');
return Response.json({ output: result.stdout, success: result.success });
}
// Work with files
if (url.pathname === '/file') {
await sandbox.writeFile('/workspace/hello.txt', 'Hello, Sandbox!');
const file = await sandbox.readFile('/workspace/hello.txt');
return Response.json({ content: file.content });
}
return new Response('Try /run or /file');
}
};
Pass options as the third argument to getSandbox() to configure sandbox
lifetime and container startup metadata:
const sandbox = getSandbox(env.Sandbox, 'tenant-workspace', {
sleepAfter: '30m',
labels: {
tenantId: 'tenant_123',
workload: 'code-workspace'
}
});
Container labels are attached to the underlying Cloudflare Container for analytics and observability. Labels are applied when the container starts; if labels are changed while a container is already running, the new labels apply the next time the container starts.
sandbox.tunnels.get(port) exposes a service running inside the
sandbox on a *.trycloudflare.com URL. No Cloudflare account or DNS
setup required — cloudflared opens a persistent QUIC connection to
Cloudflare's edge and Cloudflare hands back a hostname.
// Inside a Worker with an RPC-transport sandbox:
const tunnel = await sandbox.tunnels.get(8080);
console.log(tunnel.url);
// → https://random-words-here.trycloudflare.com
// Repeated calls for the same port return the same record:
const same = await sandbox.tunnels.get(8080);
console.log(same.url === tunnel.url); // true
// Tear down by port number or by the record:
await sandbox.tunnels.destroy(8080);
// or: await sandbox.tunnels.destroy(tunnel);
get() is idempotent: it consults a per-sandbox cache in Durable
Object storage, returns the cached record on a hit, and only spawns a
fresh cloudflared process on a miss. list() returns every cached
tunnel.
Notes:
tunnels
stub throws "RPC transport required".get(port) after a restart returns a fresh record.get() resolves.*.trycloudflare.com buffers text/event-stream responses.
WebSockets work fine.*.trycloudflare.com URLs via sandbox.tunnels.get(port)We welcome contributions from the community! See CONTRIBUTING.md for guidelines on:
This repository contains the SDK source code. Quick start:
# Clone the repo
git clone https://github.com/cloudflare/sandbox-sdk
cd sandbox-sdk
# Install dependencies
npm install
# Run tests
npm test
# Build the project
npm run build
# Type checking and linting
npm run check
See the examples directory for complete working examples:
Shell and Editor tools for OpenAI Agents SDKBeta - The SDK is in active development. APIs may change before v1.0.
(top 30 of 39)
TypeScript
97.1%
Python
1.6%