cloudflare-sandbox
ClaudeSkillz: For when you need skills, but lazier
8 stars2 forksUpdated Nov 20, 2025
npx skills add https://github.com/jackspace/claudeskillz --skill cloudflare-sandboxSKILL.md
Cloudflare Sandboxes SDK
Status: Production Ready (Open Beta)
Last Updated: 2025-10-29
Dependencies: cloudflare-worker-base, cloudflare-durable-objects (recommended for understanding)
Latest Versions: @cloudflare/sandbox@0.4.12, Docker image: cloudflare/sandbox:0.4.12
Quick Start (15 Minutes)
1. Install SDK and Setup Wrangler
npm install @cloudflare/sandbox@latest
wrangler.jsonc:
{
"name": "my-sandbox-worker",
"main": "src/index.ts",
"compatibility_flags": ["nodejs_compat"],
"containers": [{
"class_name": "Sandbox",
"image": "cloudflare/sandbox:0.4.12",
"instance_type": "lite"
}],
"durable_objects": {
"bindings": [{
"class_name": "Sandbox",
"name": "Sandbox"
}]
},
"migrations": [{
"tag": "v1",
"new_sqlite_classes": ["Sandbox"]
}]
}
Why this matters:
nodejs_compatenables Node.js APIs required by SDKcontainersdefines the Ubuntu container imagedurable_objectsbinding enables persistent routingmigrationsregisters the Sandbox class
2. Create Your First Sandbox Worker
import { getSandbox, 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> {
// Get sandbox instance (creates if doesn't exist)
const sandbox = getSandbox(env.Sandbox, 'my-first-sandbox');
// Execute Python code
const result = await sandbox.exec('python3 -c "print(2 + 2)"');
return Response.json({
output: result.stdout,
success: result.success,
exitCode: result.exitCode
});
}
};
CRITICAL:
- MUST export
{ Sandbox }from@cloudflare/sandboxin your Worker - Sandbox ID determines routing (same ID = same container)
- First request creates container (~2-3 min cold start)
- Subsequent requests are fast (<1s)
3. Deploy and Test
npm run deploy
curl https://your-worker.workers.dev
Expected output:
{
"output": "4\n",
"success": true,
"exitCode": 0
}
Architecture (Understanding the 3-Layer Model)
How Sandboxes Work
┌─────────────────────────────────────────┐
│ Your Worker (Layer 1) │
│ - Handles HTTP requests │
│ - Calls getSandbox() │
│ - Uses sandbox.exec(), writeFile(), etc│
└──────────────┬──────────────────────────┘
│ RPC via Durable Object
┌──────────────▼──────────────────────────┐
│ Durable Object (Layer 2) │
│ - Routes by sandbox ID │
│ - Maintains persistent identity │
│ - Geographic stickiness │
└──────────────┬──────────────────────────┘
│ Container API
┌──────────────▼──────────────────────────┐
│ Ubuntu Container (Layer 3) │
│ - Full Linux environment │
│ - Python 3.11, Node 20, Git, etc. │
│ - Filesystem: /workspace, /tmp, /home │
│ - Process isolation (VM-based) │
└─────────────────────────────────────────┘
Key Insight: Workers handle API logic (fast), Durable Objects route requests (persistent identity), Containers execute code (full capabilities).
Critical Container Lifecycle (Most Important Section!)
Container States
┌─────────┐ First request ┌────────┐ ~10 min idle ┌──────┐
│ Not │ ───────────────>│ Active │ ─────────────> │ Idle │
│ Created │ │ │ │ │
└─────────┘ └───┬────┘ └──┬───┘
│ ^ │
│ │ New request │
│ └──────────────────────┘
│ │
▼ ▼
Files persist ALL FILES DELETED
Processes run ALL PROCESSES KILLED
State maintained ALL STATE RESET
The #1 Gotcha: Ephemeral by Default
While Container is Active (~10 min after last request):
- ✅ Files in
/workspace,/tmp,/homepersist - ✅ Background processes keep running
- ✅ Shell environment variables remain
- ✅ Session working directories preserved
When Container Goes Idle (after inactivity):
- ❌ ALL files deleted (entire filesystem reset)
- ❌ ALL processes terminated
- ❌ ALL shell state lost
- ⚠️ Next request creates fresh container from scratch
This is NOT like a traditional server. Sandboxes are ephemeral by design.
Handling Persistence
For Important Data: Use external storage
// Save to R2 before container goes idle
await sandbox.writeFile('/workspace/data.txt', content);
const fileData = await sandbox.readFile('/workspace/data.txt');
...
Repository
jackspace/claudeskillzParent repository
Repository Stats
Stars8
Forks2
LicenseMIT License