jackspace/claudeskillz/cloudflare-sandbox

Trust tier 1
  • community
Source check pending

Checking that the SKILL.md file is still in the repository.

Guide to the Cloudflare Sandbox SDK (@cloudflare/sandbox), which runs code inside isolated Ubuntu Linux containers at the edge, routed by Durable Objects. Covers wrangler container and Durable Object bindings, getSandbox(), exec(), runCode(), gitCheckout(), session management, container lifecycle and cold starts, file handling, and state persistence. Use when executing untrusted or AI-generated code, running Python or Node.js scripts safely, building code interpreters and chat-based coding agents, issuing shell commands in isolation, working with git repositories programmatically, creating ephemeral build or CI/CD environments, processing files with system tools such as ffmpeg or imagemagick, or debugging sandbox container lifecycle, routing, and session persistence problems.

Install

npx vskill@latest install jackspace/claudeskillz/cloudflare-sandbox

SKILL.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
bash
npm install @cloudflare/sandbox@latest

wrangler.jsonc:

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_compat enables Node.js APIs required by SDK
  • containers defines the Ubuntu container image
  • durable_objects binding enables persistent routing
  • migrations registers the Sandbox class
2. Create Your First Sandbox Worker
typescript
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/sandbox in 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
bash
npm run deploy
curl https://your-worker.workers.dev

Expected output:

json
{
"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, /home persist
  • ✅ 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

typescript
// 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

typescript
// 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' });

Session Management (Game-Changer for Chat Agents)

What Are Sessions?

Sessions are bash shell contexts within one sandbox. Think terminal tabs.

Key Properties:

  • Each session has separate working directory
  • Sessions share same filesystem
  • Working directory persists across commands in same session
  • Perfect for multi-step workflows
Pattern: Chat-Based Coding Agent
typescript
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
Without Sessions (Common Mistake)
typescript
// ❌ WRONG: Each command runs in separate session
await sandbox.exec('cd /workspace/project');
await sandbox.exec('ls'); // NOT in /workspace/project (different session)
Pattern: Parallel Execution
typescript
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 })
]);

Sandbox Naming Strategies

Per-User Sandboxes (Persistent Workspace)
typescript
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

Per-Session Sandboxes (Fresh Each Time)
typescript
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

Per-Task Sandboxes (Idempotent & Traceable)
typescript
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


Core API Reference

Getting a Sandbox
typescript
import { getSandbox } from '@cloudflare/sandbox';
const sandbox = getSandbox(env.Sandbox, 'unique-sandbox-id');
// Creates new sandbox if doesn't exist, or gets existing one
Executing Commands
typescript
// Basic execution
const result = await sandbox.exec('python3 script.py');
console.log(result.stdout); // Standard output
console.log(result.stderr); // Standard error
console.log(result.exitCode); // Exit code (0 = success)
console.log(result.success); // Boolean (exitCode === 0)
// With options
const result = await sandbox.exec('npm install', {
cwd: '/workspace/project', // Working directory
timeout: 120000, // Timeout in ms (default: 30s)
session: sessionId, // Session ID
env: { NODE_ENV: 'production' } // Environment variables
});
// Always check exit codes!
if (!result.success) {
throw new Error(`Command failed: ${result.stderr}`);
}
File Operations
typescript
// Write file
await sandbox.writeFile('/workspace/data.txt', 'content');
// Read file
const content = await sandbox.readFile('/workspace/data.txt');
// Create directory
await sandbox.mkdir('/workspace/project', { recursive: true });
// List directory
const files = await sandbox.readdir('/workspace');
console.log(files); // ['data.txt', 'project']
// Delete file/directory
await sandbox.rm('/workspace/data.txt');
await sandbox.rm('/workspace/project', { recursive: true });
Git Operations
typescript
// Clone repository (optimized, faster than exec('git clone'))
await sandbox.gitCheckout(
'https://github.com/user/repo',
'/workspace/repo'
);
// Now use standard git commands
await sandbox.exec('git status', { cwd: '/workspace/repo' });
await sandbox.exec('git diff', { cwd: '/workspace/repo' });
Code Interpreter (Jupyter-like)
typescript
// Create Python context
const ctx = await sandbox.createCodeContext({ language: 'python' });
// Execute code - last expression auto-returned
const result = await sandbox.runCode(`
import pandas as pd
df = pd.DataFrame({'a': [1, 2, 3], 'b': [4, 5, 6]})
df['a'].sum() # This value is automatically returned
`, { context: ctx });
console.log(result.results[0].text); // "6"
console.log(result.logs); // Output from print() statements
console.log(result.error); // Any errors
Background Processes
typescript
// Start long-running process
const proc = await sandbox.spawn('python server.py');
console.log(proc.pid);
// Check if still running
const running = await sandbox.isProcessRunning(proc.pid);
// Kill process
await sandbox.killProcess(proc.pid);
Cleanup
typescript
// Destroy sandbox permanently
await sandbox.destroy();
// All files deleted, container removed, cannot be recovered

Critical Rules

Always Do

This is the start of the file. Read the full SKILL.md on GitHub.

Security

  • Security scanPassed, 40 of 100Pattern checks on the skill's files.
  • Model reviewPassed

Quality evaluation

  • Task evaluationNot runNo evaluation yet. Run one in Skill Studio.

Source

Popularity

Repository stars
12
Repository forks
4
7-day trend score
13

Stars and forks are for the whole GitHub repository, not this skill alone. Refreshed 5 Apr 2026, 6 months ago.

Works with

Any agent vskill installs to: 56 targets in all. These 39 have a page on this site.

  • Claude Code
  • Cursor
  • GitHub Copilot
  • Windsurf
  • Codex
  • Gemini CLI
  • Cline
  • Amp
  • Roo Code
  • Goose
  • Continue
  • Kilo Code
  • Junie
  • Trae
  • OpenHands
  • Qwen Code
  • AI Agent
  • Tabnine Chat
  • Sourcegraph Cody
  • Amazon Q
  • Firebase Genkit
  • Sweep
  • Devin
  • Phind
  • Mentat
  • Claude Desktop
  • Aider
  • GPT Pilot
  • Plandex
  • bolt.new
  • v0
  • Replit Agent
  • Anse
  • TypingMind
  • BetterChatGPT
  • LibreChat
  • Warp AI
  • Pieces
  • Fig AI
Embed badge
vskill VERIFIED badge
[![vskill VERIFIED](https://verified-skill.com/api/v1/skills/jackspace/claudeskillz/cloudflare-sandbox/badge)](https://verified-skill.com/skills/jackspace/claudeskillz/cloudflare-sandbox)

Something wrong with this skill or its page? Tell us.