Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/cloudflare/sandbox-sdk/llms.txt

Use this file to discover all available pages before exploring further.

The Sandbox SDK provides flexible command execution through the exec() method. You can run any shell command and get immediate results, or stream output in real-time for long-running operations.

Basic command execution

The simplest way to execute a command is with exec(), which waits for the command to complete and returns the full result:
const sandbox = getSandbox(env.Sandbox, 'my-sandbox');

const result = await sandbox.exec('echo "Hello, World!"');

console.log(result.stdout);  // "Hello, World!"
console.log(result.exitCode); // 0
console.log(result.success);  // true

Understanding the result

Every exec() call returns an ExecResult object with complete execution details:
interface ExecResult {
  success: boolean;      // true if exitCode === 0
  exitCode: number;      // Process exit code
  stdout: string;        // Standard output content
  stderr: string;        // Standard error content
  command: string;       // Command that was executed
  duration: number;      // Execution time in milliseconds
  timestamp: string;     // ISO timestamp when command started
  sessionId?: string;    // Session ID if provided
}
const result = await sandbox.exec('python3 -c "print(2 + 2)"');
// {
//   success: true,
//   exitCode: 0,
//   stdout: "4\n",
//   stderr: "",
//   duration: 45
// }

Streaming output

For long-running commands, stream output in real-time instead of waiting for completion:
const result = await sandbox.exec('npm install', {
  stream: true,
  onOutput: (stream, data) => {
    if (stream === 'stdout') {
      console.log('Output:', data);
    } else {
      console.error('Error:', data);
    }
  },
  onComplete: (result) => {
    console.log('Command finished with exit code:', result.exitCode);
  }
});
Streaming is perfect for commands that produce incremental output like package installations, builds, or log tailing.

Command options

Customize command execution with various options:

Timeout

Set a maximum execution time to prevent commands from running indefinitely:
try {
  await sandbox.exec('sleep 10', {
    timeout: 3000  // Timeout after 3 seconds
  });
} catch (error) {
  console.error('Command timed out');
}

Environment variables

Provide environment variables for a single command without affecting the session:
const result = await sandbox.exec('echo $API_KEY', {
  env: {
    API_KEY: 'secret-key',
    DEBUG: 'true'
  }
});
Environment variables passed to exec() only apply to that specific command. They don’t persist in the session. Use setEnvVars() for persistent environment variables.

Working directory

Change the working directory for a specific command:
const result = await sandbox.exec('ls -la', {
  cwd: '/workspace/project'
});

All options combined

const result = await sandbox.exec('python script.py', {
  timeout: 60000,  // 60 second timeout
  env: {
    PYTHONPATH: '/workspace/lib',
    DEBUG: '1'
  },
  cwd: '/workspace/scripts',
  stream: true,
  onOutput: (stream, data) => {
    console.log(`[${stream}]`, data);
  },
  onError: (error) => {
    console.error('Execution failed:', error.message);
  }
});

Chaining commands

Use shell operators to chain multiple commands:
// Run commands sequentially
await sandbox.exec('cd /workspace && npm install && npm run build');

// Run with conditional execution
await sandbox.exec('test -f config.json || cp config.example.json config.json');

// Pipe output between commands
const result = await sandbox.exec('cat data.txt | grep "error" | wc -l');

Running Python and Node.js

The sandbox comes with Python 3.11 and Node.js 20 pre-installed:
const result = await sandbox.exec(
  'python3 -c "import sys; print(sys.version)"'
);
console.log(result.stdout);
// "3.11.6 (main, ...)\n"

Error handling

Always check command results for errors:
const result = await sandbox.exec('make build');

if (!result.success) {
  console.error('Build failed!');
  console.error('Exit code:', result.exitCode);
  console.error('Error output:', result.stderr);
  throw new Error(`Build failed with exit code ${result.exitCode}`);
}

console.log('Build succeeded:', result.stdout);
The exec() method doesn’t throw errors for non-zero exit codes. Check result.success or result.exitCode to determine if the command succeeded.

Cancelling commands

Use AbortSignal to cancel long-running commands:
const controller = new AbortController();

// Cancel after 5 seconds
setTimeout(() => controller.abort(), 5000);

try {
  await sandbox.exec('long-running-process', {
    signal: controller.signal
  });
} catch (error) {
  if (error.message.includes('aborted')) {
    console.log('Command was cancelled');
  }
}

Best practices

1
Use streaming for long operations
2
Stream output for commands that take more than a few seconds. This provides user feedback and helps debug issues.
3
Set appropriate timeouts
4
Always set timeouts for operations that might hang. This prevents resource exhaustion and provides better error messages.
5
Handle errors explicitly
6
Check result.success before using command output. Non-zero exit codes indicate failures that need handling.
7
Escape special characters
8
When constructing commands with user input, properly escape special characters or use command arrays:
9
// Bad - vulnerable to injection
await sandbox.exec(`cat ${userFilename}`);

// Good - escape shell special characters
import { shellEscape } from '@repo/shared';
await sandbox.exec(`cat ${shellEscape(userFilename)}`);

Next steps

Managing files

Read, write, and organize files in your sandbox

Running processes

Start long-running background processes

Code interpreter

Execute Python and JavaScript with rich outputs

Streaming output

Advanced streaming patterns and SSE events