Cloudflare Sandboxes SDK for secure code execution in Linux containers at edge. Use for untrusted code, Python/Node.js scripts, AI code interpreters, git operations.
npx skills add https://github.com/secondsky/claude-skills --skill cloudflare-sandbox
Status: Production Ready (Open Beta)
Last Updated: 2025-12-10
Dependencies: cloudflare-worker-base, cloudflare-durable-objects (recommended for understanding)
Latest Versions: @cloudflare/[email protected], Docker image: cloudflare/sandbox:0.6.3-python
⚠️ BREAKING CHANGE (v0.6.0): Python is no longer included in the default image. Use cloudflare/sandbox:<version>-python for Python support (~1.3GB with data science packages). The lean variant (~600-800MB) excludes Python.
bun add @cloudflare/sandbox@latest # preferred
# or: bun add @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.6.3-python",
"instance_type": "lite"
}],
"durable_objects": {
"bindings": [{
"class_name": "Sandbox",
"name": "Sandbox"
}]
},
"migrations": [{
"tag": "v1",
"new_sqlite_classes": ["Sandbox"]
}]
}
Why this matters:
nodejs_compat enables Node.js APIs required by SDKcontainers defines the Ubuntu container imagedurable_objects binding enables persistent routingmigrations registers the Sandbox classimport { 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:
{ Sandbox } from @cloudflare/sandbox in your Workernpm run deploy
curl https://your-worker.workers.dev
Expected output:
{
"output": "4\n",
"success": true,
"exitCode": 0
}
Sandbox SDK packages grant container access — verify before installing to prevent unauthorized code execution. Follow supply chain security best practices:
npm config set ignore-scripts true (or Bun: disabled by default)socket package score npm <pkg> or use socket npm install <pkg> to check packagesLoad the dependency-upgrade skill for full security configuration including Socket CLI integration, cooldown setup, lockfile validation, and CI enforcement.
┌─────────────────────────────────────────┐
│ 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).
┌─────────┐ 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
While Container is Active (~10 min after last request):
/workspace, /tmp, /home persistWhen Container Goes Idle (after inactivity):
This is NOT like a traditional server. Sandboxes are ephemeral by design.
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');
await env.R2.put('backup/data.txt', fileData);
// Restore on next request
const restored = await env.R2.get('backup/data.txt');
if (restored) {
await sandbox.writeFile('/workspace/data.txt', await restored.text());
}
For Build Artifacts: Accept ephemerality or use caching
// Check if setup needed (handles cold starts)
const exists = await sandbox.readdir('/workspace/project').catch(() => null);
if (!exists) {
await sandbox.gitCheckout(repoUrl, '/workspace/project');
await sandbox.exec('npm install', { cwd: '/workspace/project' });
}
// Now safe to run build
await sandbox.exec('npm run build', { cwd: '/workspace/project' });
Sessions are bash shell contexts within one sandbox. Think terminal tabs.
Key Properties:
type ConversationState = {
sandboxId: string;
sessionId: string;
};
// First message: Create sandbox and session
const sandboxId = `user-${userId}`;
const sandbox = getSandbox(env.Sandbox, sandboxId);
const sessionId = await sandbox.createSession();
// Store in conversation state (database, KV, etc.)
await env.KV.put(`conversation:${conversationId}`, JSON.stringify({
sandboxId,
sessionId
}));
// Later messages: Reuse same session
const state = await env.KV.get(`conversation:${conversationId}`);
const { sandboxId, sessionId } = JSON.parse(state);
const sandbox = getSandbox(env.Sandbox, sandboxId);
// Commands run in same context
await sandbox.exec('cd /workspace/project', { session: sessionId });
await sandbox.exec('ls -la', { session: sessionId }); // Still in /workspace/project
await sandbox.exec('git status', { session: sessionId }); // Still in /workspace/project
// ❌ WRONG: Each command runs in separate session
await sandbox.exec('cd /workspace/project');
await sandbox.exec('ls'); // NOT in /workspace/project (different session)
const session1 = await sandbox.createSession();
const session2 = await sandbox.createSession();
// Run different tasks simultaneously
await Promise.all([
sandbox.exec('python train_model.py', { session: session1 }),
sandbox.exec('node generate_reports.js', { session: session2 })
]);
const sandbox = getSandbox(env.Sandbox, `user-${userId}`);
Pros: User's work persists while actively using (10 min idle time)
Cons: Geographic lock-in (first request determines location)
Use Cases: Interactive notebooks, IDEs, persistent workspaces
const sandboxId = `session-${Date.now()}-${crypto.randomUUID()}`;
const sandbox = getSandbox(env.Sandbox, sandboxId);
// Always destroy after use
await sandbox.destroy();
Pros: Clean environment, no state pollution
Cons: No persistence between requests
Use Cases: One-shot code execution, CI/CD, testing
const sandbox = getSandbox(env.Sandbox, `build-${repoName}-${commitSha}`);
Pros: Reproducible, debuggable, cacheable
Cons: Need explicit cleanup strategy
Use Cases: Build systems, data pipelines, automated workflows
The Sandbox SDK provides methods for command execution, file operations, Git operations, code interpretation (Jupyter-like), background processes, and cleanup.
📖 Load references/api-reference.md when you need detailed API method signatures, parameter options, or implementation examples for:
✅ Check exit codes - if (!result.success) { handle error }
✅ Use sessions for multi-step workflows - Preserve working directory
✅ Handle cold starts - Check if files exist before assuming they're there
✅ Set timeouts - Prevent hanging on long operations
✅ Destroy ephemeral sandboxes - Cleanup temp/session-based sandboxes
✅ Use external storage for persistence - R2/KV/D1 for important data
✅ Validate user input - Sanitize before exec() to prevent command injection
✅ Export Sandbox class - export { Sandbox } from '@cloudflare/sandbox'
❌ Assume files persist after idle - Container resets after ~10 min
❌ Ignore exit codes - Always check result.success or result.exitCode
❌ Chain commands without sessions - cd /dir then ls won't work
❌ Execute unsanitized user input - Use code interpreter or validate thoroughly
❌ Forget nodejs_compat flag - Required in wrangler.jsonc
❌ Skip migrations - Durable Objects need migration entries
❌ Use .workers.dev for preview URLs - Need custom domain
❌ Create unlimited sandboxes - Destroy ephemeral ones to avoid leaks
This skill prevents 10 documented issues:
Error: ReferenceError: fetch is not defined or Buffer is not defined
Source: https://developers.cloudflare.com/sandbox/get-started/
Why It Happens: SDK requires Node.js APIs not available in standard Workers
Prevention: Add "compatibility_flags": ["nodejs_compat"] to wrangler.jsonc
Error: Error: Class 'Sandbox' not found
Source: https://developers.cloudflare.com/durable-objects/
Why It Happens: Durable Objects must be registered via migrations
Prevention: Include migrations array in wrangler.jsonc
Error: Files disappear after inactivity
Source: https://developers.cloudflare.com/sandbox/concepts/sandboxes/
Why It Happens: Containers go idle after ~10 min, all state reset
Prevention: Use external storage (R2/KV) or check existence on each request
Error: Commands execute in wrong directory
Source: https://developers.cloudflare.com/sandbox/concepts/sessions/
Why It Happens: Each exec() uses new session unless explicitly specified
Prevention: Create session with createSession(), pass to all related commands
Error: Assuming command succeeded when it failed
Source: Shell best practices
Why It Happens: Not checking result.success or result.exitCode
Prevention: Always check: if (!result.success) throw new Error(result.stderr)
Error: Commands fail because dependencies aren't installed
Source: https://developers.cloudflare.com/sandbox/concepts/sandboxes/
Why It Happens: Container resets after idle period
Prevention: Check if setup needed before running commands
Error: Failed to build container during local development
Source: https://developers.cloudflare.com/sandbox/get-started/
Why It Happens: Local dev requires Docker daemon
Prevention: Ensure Docker Desktop is running before npm run dev
Error: API methods not available or behaving unexpectedly
Source: GitHub issues
Why It Happens: npm package version doesn't match Docker image version
Prevention: Keep @cloudflare/sandbox package and cloudflare/sandbox image in sync
Error: Resource exhaustion, unexpected costs
Source: Resource management best practices
Why It Happens: Creating sandboxes without destroying them
Prevention: await sandbox.destroy() in finally block for temp sandboxes
Error: Security breach from unsanitized user input
Source: Security best practices
Why It Happens: Passing user input directly to exec()
Prevention: Use code interpreter API or validate/sanitize input thoroughly
{
"name": "my-sandbox-app",
"main": "src/index.ts",
"compatibility_date": "2025-10-29",
"compatibility_flags": ["nodejs_compat"], // ← REQUIRED
"containers": [{
"class_name": "Sandbox",
"image": "cloudflare/sandbox:0.6.3-python", // ← Use -python for Python support
"instance_type": "lite"
}],
"durable_objects": {
"bindings": [{"class_name": "Sandbox", "name": "Sandbox"}]
},
"migrations": [{
"tag": "v1",
"new_sqlite_classes": ["Sandbox"]
}]
}
Four production-ready patterns for building with Cloudflare Sandboxes: one-shot code execution, persistent user workspaces, CI/CD pipelines, and AI agent integration.
📖 Load references/patterns.md when you need complete implementation examples for:
setup-sandbox-binding.sh - Interactive wrangler.jsonc configurationtest-sandbox.ts - Validation script to test sandbox setupExample Usage:
# Setup wrangler config
./scripts/setup-sandbox-binding.sh
# Test sandbox
bunx tsx scripts/test-sandbox.ts
references/persistence-guide.md - Deep dive on container lifecycle and persistencereferences/session-management.md - Advanced session patterns and best practicesreferences/common-errors.md - Complete list of errors with solutionsreferences/naming-strategies.md - Choosing sandbox IDs for different use casesWhen Claude should load these:
persistence-guide.md when debugging state issues or cold startssession-management.md when building multi-step workflows or chat agentscommon-errors.md when encountering specific errorsnaming-strategies.md when designing sandbox architecture📖 Load references/advanced.md for production patterns:
Package: @cloudflare/[email protected] | Docker: cloudflare/sandbox:0.6.3-python
Docs: Cloudflare Sandboxes | API Reference | GitHub SDK
Run Python code in the cloud with serverless containers, GPUs, and autoscaling. Use when deploying ML models, running batch processing jobs, scheduling compute-intensive tasks, or serving APIs that require GPU acceleration or dynamic scaling.
Advanced GitHub Actions workflow automation with AI swarm coordination, intelligent CI/CD pipelines, and comprehensive repository management
Google Cloud Platform CLI - manage GCP resources including Compute Engine, Cloud Run, GKE, Cloud Functions, Storage, BigQuery, and more.
Expert backend architect specializing in scalable API design, microservices architecture, and distributed systems. Masters REST/GraphQL/gRPC APIs, event-driven architectures, service mesh patterns, and modern backend frameworks. Handles service boundary definition, inter-service communication, resilience patterns, and observability. Use PROACTIVELY when creating new backend services or APIs.
Run Python code in the cloud with serverless containers, GPUs, and autoscaling. Use when deploying ML models, running batch processing jobs, scheduling compute-intensive tasks, or serving APIs that require GPU acceleration or dynamic scaling.
Aspire skill covering the Aspire CLI, AppHost orchestration, service discovery, integrations, MCP server, VS Code extension, Dev Containers, GitHub Codespaces, templates, dashboard, and deployment. Use when the user asks to create, run, debug, configure, deploy, or troubleshoot an Aspire distributed application.
Audits Python + BigQuery pipelines for cost safety, idempotency, and production readiness. Returns a structured report with exact patch locations.
Microsoft Store Developer CLI (msstore) for publishing Windows applications to the Microsoft Store. Use when asked to configure Store credentials, list Store apps, check submission status, publish submissions, manage package flights, set up CI/CD for Store publishing, or integrate with Partner Center. Supports Windows App SDK/WinUI, UWP, .NET MAUI, Flutter, Electron, React Native, and PWA applications.
Take secondsky/cloudflare-sandbox from the repository into ~/.claude/skills for personal
use, or into .claude/skills inside a project.
The agent identifies a skill by the name field in its header. Two skills with the
same name cannot sit side by side — one of them will be ignored.
The instructions reference npm.
Without those the skill loads but fails at the first command.