Skip to main content

Documentation Index

Fetch the complete documentation index at: https://e2b-squash-sandbox-pages.mintlify.app/llms.txt

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

Templates define a sandbox’s base environment, but many workloads need dynamic configuration — different packages per user, files uploaded at request time, or settings that change between runs. This page covers patterns for customizing sandboxes after creation.

When to use templates vs. runtime setup

Use caseTemplateRuntime
Same packages for every sandboxYes
Packages vary per user or requestYes
Static config files, shared across sandboxesYes
User-uploaded files or per-request dataYes
Secrets that change per requestYes
When in doubt: if every sandbox needs it, put it in a template. If it varies per user or request, handle it at runtime.

Install packages

Use sandbox.commands.run() to install packages after the sandbox starts. This is useful when different users or requests need different dependencies.
import { Sandbox } from 'e2b'

const sandbox = await Sandbox.create()

// Install Python packages
await sandbox.commands.run('pip install pandas numpy matplotlib')

// Install system packages
await sandbox.commands.run('sudo apt-get update && sudo apt-get install -y ffmpeg')

// Install Node.js packages
await sandbox.commands.run('npm install express')
For packages you install in every sandbox, add them to a template instead. Template-based installs are faster because they’re baked into the sandbox image.

Speed up repeated installs with snapshots

If multiple sandboxes need the same runtime setup, install once and snapshot the result. New sandboxes start from the snapshot with everything already installed.
import { Sandbox } from 'e2b'

// First time: install and snapshot
const sandbox = await Sandbox.create()
await sandbox.commands.run('pip install pandas numpy scikit-learn')

const snapshot = await sandbox.createSnapshot()
console.log('Snapshot ID:', snapshot.snapshotId)

// Later: start from snapshot — packages are already installed
const fast = await Sandbox.create(snapshot.snapshotId)

Upload files

Use sandbox.files.write() to upload configuration files, scripts, or user data into the sandbox. See the Filesystem page for the full file operations API.
import { Sandbox } from 'e2b'

const sandbox = await Sandbox.create()

// Upload a configuration file
await sandbox.files.write('/home/user/config.json', JSON.stringify({
  apiEndpoint: 'https://api.example.com',
  maxRetries: 3,
}))

// Upload a script
await sandbox.files.write('/home/user/analyze.py', `
import json
with open('config.json') as f:
    config = json.load(f)
print(f"Connecting to {config['apiEndpoint']}")
`)

// Run the uploaded script
const result = await sandbox.commands.run('cd /home/user && python analyze.py')
console.log(result.stdout)

Use start_cmd for initialization

If your template supports a start command, you can override it at runtime to customize sandbox initialization.
import { Sandbox } from 'e2b'

const sandbox = await Sandbox.create('my-template', {
  startCmd: 'python /home/user/setup.py && nginx -g "daemon off;"',
})

Combine patterns

For complex setups, combine multiple approaches. Here’s an example setting up a data analysis sandbox per user:
import { Sandbox } from 'e2b'

async function createAnalysisSandbox(userId, dataUrl, packages) {
  const sandbox = await Sandbox.create({
    timeoutMs: 10 * 60 * 1000,
    lifecycle: {
      onTimeout: 'pause',
      autoResume: true,
    },
    envs: {
      USER_ID: userId,
      DATA_URL: dataUrl,
    },
  })

  // Install user-specific packages
  if (packages.length > 0) {
    await sandbox.commands.run(`pip install ${packages.join(' ')}`)
  }

  // Upload analysis script
  await sandbox.files.write('/home/user/run.py', `
import os, urllib.request
urllib.request.urlretrieve(os.environ['DATA_URL'], '/home/user/data.csv')
print(f"Data downloaded for user {os.environ['USER_ID']}")
  `)

  await sandbox.commands.run('python /home/user/run.py')
  return sandbox
}