Skip to content

Sandbox

Amplify runs all code in a WebContainer : a browser-native Node.js runtime powered by WebAssembly. No Docker, no remote servers, no cloud dependencies. Everything runs in your browser tab.

What are WebContainers?

WebContainers are a Node.js runtime that runs entirely in the browser using WebAssembly. They provide:

  • A complete Node.js environment : npm, node, shell commands all work
  • An in-memory filesystem : reads and writes happen in browser memory
  • Network access : Can fetch packages from npm registries
  • Process spawning : Can run dev servers, build tools, and shell commands
Boot configuration

Amplify boots the WebContainer with specific settings:

typescript
WebContainer.boot({
  coep: 'credentialless',  // Required for SharedArrayBuffer
  workdirName: 'project',   // Working directory name
  forwardPreviewErrors: true // Send preview errors to parent
})

The coep: 'credentialless' header is required for WebContainers. Without it, SharedArrayBuffer (needed for WebAssembly) will not be available in the browser. This header must be set on your hosting platform.

Terminal (xterm.js)

Amplify's terminal uses @xterm/xterm with the FitAddon and WebLinksAddon. It supports three dedicated shell types:

ShellPurposeSpawning
#amplifyTerminalAI's shell (commands from tool calls)/bin/jsh --osc via AmplifyShell
#initTerminalProject auto-setup (npm install + dev)/bin/jsh --osc via TerminalStore
#terminals[]User-created terminals/bin/jsh --osc via newShellProcess()

Terminal configuration:

  • cursorBlink: true, convertEol: true
  • fontSize: 12, fontFamily: 'Menlo, courier-new, courier, monospace'
  • scrollback: 1000, rightClickSelectsWord: true
  • Read-only mode: disableStdin: readonly, transparent cursor
  • AmplifyShell — AI command execution

    The AmplifyShell class handles AI command execution:

    1. init() : spawns /bin/jsh --osc and waits for \x1b]654;interactive\x07 OSC signal (shell ready)
    2. executeCommand(sessionId, command) : writes command to jsh input, waits for completion via exit marker \x1b]654;exit:${sessionId}\x07
    3. spawnDetached(command) : spawns command directly via webcontainer.spawn() (not through jsh) — for backgrounded processes like dev servers

    The separation of AI terminal from init terminal ensures that Ctrl+C in the AI terminal doesn't kill the running dev server.

  • Auto-setup on project load

    When a project template is injected, runProjectAutoSetup() runs:

    1. Step 1: Executes project.setupCommand (e.g., npm install) on the init terminal — waits for completion
    2. Step 2: Executes project.startCommand (e.g., npm run dev) via shell.spawnDetached() — backgrounded

    Package manager detection (detectProjectCommands()):

    • Checks packageManager field in package.json → lockfile presence
    • Supported: npm, pnpm, yarn v1 (classic)
    • Not supported: bun (native Zig binary), yarn berry (v2+)

File system integration

The FilesStore bridges the AI layer with the WebContainer filesystem.

File map structure:

typescript
type FileMap = Record<string, Dirent | undefined>

type Dirent = File | Folder
interface File { type: 'file'; content: string; isBinary: boolean; isLocked?: boolean }
interface Folder { type: 'folder' }

How files flow between AI and WebContainer:

  1. AI calls read_file → reads from files map shipped with the request
  2. AI calls create_file → returns mutation signal → client applies to FilesStore → writes to WebContainer via webcontainer.fs.writeFile()
  3. WebContainer changes → path watcher events → FilesStore updates → re-syncs AI file map
Binary detection

Amplify uses the istextorbinary npm package to detect binary files. Binary files are stored as Buffer objects from node:buffer and are never sent to the AI for reading.

Preview system

The PreviewsStore manages live preview URLs from WebContainer server detection.

How preview works:

  1. webcontainer.on('server-ready', (port, url)) → adds PreviewInfo { port, ready, baseUrl }
  2. Preview rendered in an iframe with sandbox attributes: allow-scripts allow-forms allow-popups allow-modals allow-storage-access-by-user-activation allow-same-origin
  3. Cross-tab sync via BroadcastChannel('preview-updates') and BroadcastChannel('storage-sync-channel')
  4. Preview refresh: debounced 300ms delay

Preview features:

  • Device mode: Configurable width with resize handles, landscape support, device frames (mobile/desktop)
  • Inspector integration: postMessage bridge between iframe and parent (INSPECTOR_ACTIVATE, INSPECTOR_READY, INSPECTOR_CLICK)
  • Screenshot overlay: Capture preview screenshots for context

Git integration (isomorphic-git)

Amplify uses isomorphic-git for Git operations within the WebContainer. This enables:

  • git clone — Clone repositories directly in the browser
  • git commit — Save project snapshots
  • git push — Push to GitHub or other remotes

The /api/git-proxy route proxies Git requests to handle authentication. Git information is available via /api/git-info which returns { branch, commit, isDirty, remoteUrl, lastCommit }.

Known limitations

WebContainers have inherent limitations due to running in a browser:

LimitationDetail
No native binariessharp, bcrypt, node-gyp modules fail
No DockerCannot run Docker or container processes
Memory limits2–4 GB typical browser constraint
No persistent filesystemIn-memory only; reload clears unless persisted to IndexedDB
No bun supportBun's native Zig binary can't run in WASM Node.js runtime
No yarn berryYarn v2+ (Plug'n'Play) not supported
Network limitationsSome WebSocket configs may need adjustment
SSL requiredSharedArrayBuffer needs secure context (HTTPS)
Migration alternatives

If WebContainer limitations block your project, consider migrating to Docker, Firecracker, or Kubernetes. See the Migration guide for details.

Learn about migration options