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:
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:
| Shell | Purpose | Spawning |
#amplifyTerminal | AI's shell (commands from tool calls) | /bin/jsh --osc via AmplifyShell |
#initTerminal | Project auto-setup (npm install + dev) | /bin/jsh --osc via TerminalStore |
#terminals[] | User-created terminals | /bin/jsh --osc via newShellProcess() |
Terminal configuration:
cursorBlink: true,convertEol: truefontSize: 12,fontFamily: 'Menlo, courier-new, courier, monospace'scrollback: 1000,rightClickSelectsWord: true- Read-only mode:
disableStdin: readonly, transparent cursor
AmplifyShell — AI command execution
The
AmplifyShellclass handles AI command execution:- init() : spawns
/bin/jsh --oscand waits for\x1b]654;interactive\x07OSC signal (shell ready) - executeCommand(sessionId, command) : writes command to jsh input, waits for completion via exit marker
\x1b]654;exit:${sessionId}\x07 - 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.
- init() : spawns
Auto-setup on project load
When a project template is injected,
runProjectAutoSetup()runs:- Step 1: Executes
project.setupCommand(e.g.,npm install) on the init terminal — waits for completion - Step 2: Executes
project.startCommand(e.g.,npm run dev) viashell.spawnDetached()— backgrounded
Package manager detection (
detectProjectCommands()):- Checks
packageManagerfield in package.json → lockfile presence - Supported: npm, pnpm, yarn v1 (classic)
- Not supported: bun (native Zig binary), yarn berry (v2+)
- Step 1: Executes
File system integration
The FilesStore bridges the AI layer with the WebContainer filesystem.
File map structure:
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:
- AI calls
read_file→ reads fromfilesmap shipped with the request - AI calls
create_file→ returns mutation signal → client applies to FilesStore → writes to WebContainer viawebcontainer.fs.writeFile() - 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:
webcontainer.on('server-ready', (port, url))→ addsPreviewInfo { port, ready, baseUrl }- 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 - Cross-tab sync via
BroadcastChannel('preview-updates')andBroadcastChannel('storage-sync-channel') - 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 browsergit commit— Save project snapshotsgit 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:
| Limitation | Detail |
| No native binaries | sharp, bcrypt, node-gyp modules fail |
| No Docker | Cannot run Docker or container processes |
| Memory limits | 2–4 GB typical browser constraint |
| No persistent filesystem | In-memory only; reload clears unless persisted to IndexedDB |
| No bun support | Bun's native Zig binary can't run in WASM Node.js runtime |
| No yarn berry | Yarn v2+ (Plug'n'Play) not supported |
| Network limitations | Some WebSocket configs may need adjustment |
| SSL required | SharedArrayBuffer 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