Skip to content

Migration Guide

ConceptWebContainersNodeboxbolo
BootWebContainer.boot()new Nodebox({ iframe }); .connect()boot()
Mount files.mount(files)fs.init(fileMap)vfs.writeFile(path, content) per file, or vfs.restore(snapshot) for bulk
Run command.spawn('node', ['file.js'])shell.runCommand('node', ['file.js'])shell.execute('runtime run file.js')
Streaming outputprocess.output.pipeTo(writable)shell output streamexecute(cmd, { stdout, stderr }) callbacks
npm install.spawn('npm', ['install'])shell.runCommand('npm', ['install'])shell.execute('npm install')
Preview URL.on('server-ready', handler)port forwardingSWSandbox virtual origin via iframe
Untrusted sandboxshell.execute('agent run file.js') (QuickJS tier)
Trusted user codeNative (full Node.js)Native (polyfills)shell.execute('runtime run file.js') (V8 Web Worker)
import { WebContainer } from '@webcontainer/api';
const container = await WebContainer.boot();
await container.mount({
'index.js': { file: { contents: 'console.log("hello")' } }
});
const proc = await container.spawn('node', ['index.js']);
proc.output.pipeTo(new WritableStream({ write: (chunk) => console.log(chunk) }));
await proc.exit;
import { boot } from '@bolojs/runtime';
const container = await boot();
await container.mount({
'index.js': { file: { contents: 'console.log("hello")' } },
});
const proc = container.spawn('node', ['index.js']);
proc.output.pipeTo(new WritableStream({ write: (chunk) => console.log(chunk) }));
await proc.exit;

Key differences:

  • boot() mirrors @webcontainer/api’s shape directly — same mount()/spawn()/fs/ on('server-ready')/teardown() surface
  • spawn()’s output is a ReadableStream<string> (not bytes); container.fs exposes readFile/writeFile/mkdir/rm/readdir/rename/watch (fs.promises-style, no stat/lstat/symlinks in v1.0)
  • The lower-level primitives (VfsBus, SWSandbox, ShellService, RuntimeWorker, SandboxPool) are still available directly for callers who want manual wiring instead of boot()
import { Nodebox } from '@codesandbox/nodebox';
const sandbox = new Nodebox({ iframe: document.getElementById('preview') });
await sandbox.connect();
await sandbox.fs.init({
'index.js': 'console.log("hello")',
});
const shell = await sandbox.shell.create();
const { stdout } = await shell.runCommand('node', ['index.js']);
console.log(stdout);
// (same boot sequence as above)
// Bulk mount via snapshot
vfs.restore({
'/index.js': 'console.log("hello")',
});
// Run
const result = await shell.execute('runtime run /index.js', {
stdout: (chunk) => process.stdout.write(chunk),
});

Key differences:

  • fs.init(fileMap)vfs.restore(snapshot) for bulk mount, or multiple vfs.writeFile calls
  • shell.runCommand('node', ['file.js'])shell.execute('runtime run file.js')
  • npm, runtime, and agent are special-cased to wire into the container’s package manager/runtime worker/sandbox pool; every other command line runs through a real bash interpreter (just-bash) backed by VfsBus, with full support for pipes, redirection, quoting, and POSIX builtins (ls, cat, mkdir, rm, cp, mv, grep, sed, etc.)

These features exist in WebContainers or Nodebox but are not yet implemented:

FeatureStatus
npm-published packagesRoadmap
Full Node.js native package support (NAPI)Not planned (WASM/JS only)
fork() / clusterNot planned