Skip to main content

Overview

The Sandbox class is the main entry point for creating a fully-functional Linux-like operating system in the browser. It orchestrates the kernel, virtual filesystem, shell, and command registry into a unified environment.

Creating a Sandbox

import { Sandbox } from '@lifo-sh/core';

const sandbox = await Sandbox.create({
  persist: false,
  cwd: '/home/user',
  files: {
    '/home/user/hello.txt': 'Hello, World!'
  }
});

Static Methods

create()

Create a new Sandbox instance. Orchestrates all boot steps: Kernel, VFS, Registry, Shell, and config sourcing.
static async create(options?: SandboxOptions): Promise<Sandbox>
options
SandboxOptions
Configuration options for the sandbox
sandbox
Sandbox
A fully initialized Sandbox instance
Example:
const sandbox = await Sandbox.create({
  persist: true,
  cwd: '/home/user/projects',
  env: {
    NODE_ENV: 'development'
  },
  files: {
    '/home/user/package.json': JSON.stringify({ name: 'my-app' }),
    '/home/user/README.md': '# My Project'
  }
});

Instance Properties

commands

Programmatic command execution interface.
readonly commands: SandboxCommands
Example:
const result = await sandbox.commands.run('ls -la /home/user');
console.log(result.stdout);
See SandboxCommands API for available methods.

fs

Filesystem operations interface.
readonly fs: SandboxFs
Example:
await sandbox.fs.writeFile('/home/user/data.json', '{"key": "value"}');
const content = await sandbox.fs.readFile('/home/user/data.json');
See SandboxFs API for available methods.

env

Environment variables.
readonly env: Record<string, string>
Example:
console.log(sandbox.env.HOME); // '/home/user'
console.log(sandbox.env.PATH); // '/usr/bin:/bin'

kernel

Direct access to the underlying Kernel instance (power-user escape hatch).
readonly kernel: Kernel
See Kernel for details.

shell

Direct access to the underlying Shell instance (power-user escape hatch).
readonly shell: Shell
See Shell for details.

cwd

Current working directory. Can be read and written.
get cwd(): string
set cwd(path: string)
Example:
console.log(sandbox.cwd); // '/home/user'
sandbox.cwd = '/tmp';
console.log(sandbox.cwd); // '/tmp'

Instance Methods

mountNative()

Mount a native filesystem directory into the virtual filesystem. Only works in Node.js environments.
mountNative(
  virtualPath: string,
  hostPath: string,
  options?: { readOnly?: boolean; fsModule?: NativeFsModule }
): void
virtualPath
string
required
Path inside the virtual filesystem where the mount will appear (e.g., “/mnt/project”)
hostPath
string
required
Host filesystem path to mount (e.g., “/home/user/my-project”)
options
object
Example:
// Node.js only
import fs from 'node:fs';

sandbox.mountNative('/mnt/project', '/home/user/my-project', {
  readOnly: false,
  fsModule: fs
});

// Now VFS operations on /mnt/project/* delegate to the real filesystem
await sandbox.fs.writeFile('/mnt/project/output.txt', 'data');

unmountNative()

Unmount a previously mounted filesystem.
unmountNative(virtualPath: string): void
virtualPath
string
required
The virtual path that was passed to mountNative()
Example:
sandbox.unmountNative('/mnt/project');

attach()

Attach a headless sandbox to a terminal, enabling visual mode.
attach(terminal: ITerminal): void
terminal
ITerminal
required
Terminal instance to attach to
Example:
import { Terminal } from '@xterm/xterm';

const terminal = new Terminal();
terminal.open(document.getElementById('terminal'));
sandbox.attach(terminal);

detach()

Detach from visual mode.
detach(): void

exportSnapshot()

Export the entire VFS as a tar.gz snapshot.
async exportSnapshot(): Promise<Uint8Array>
snapshot
Uint8Array
Compressed tar.gz archive of the entire filesystem
Example:
const snapshot = await sandbox.exportSnapshot();

// Save to file (Node.js)
import fs from 'node:fs';
fs.writeFileSync('snapshot.tar.gz', snapshot);

// Download in browser
const blob = new Blob([snapshot], { type: 'application/gzip' });
const url = URL.createObjectURL(blob);
const a = document.createElement('a');
a.href = url;
a.download = 'sandbox-snapshot.tar.gz';
a.click();

importSnapshot()

Restore VFS from a tar.gz snapshot.
async importSnapshot(data: Uint8Array): Promise<void>
data
Uint8Array
required
Compressed tar.gz archive to restore from
Example:
// Load from file (Node.js)
import fs from 'node:fs';
const snapshot = fs.readFileSync('snapshot.tar.gz');
await sandbox.importSnapshot(snapshot);

// Upload in browser
const file = await fileInput.files[0].arrayBuffer();
await sandbox.importSnapshot(new Uint8Array(file));

destroy()

Destroy the sandbox, releasing all resources.
destroy(): void
Example:
sandbox.destroy();
// Sandbox is now unusable

SandboxCommands Interface

The commands property provides programmatic command execution.

run()

Execute a shell command and capture output.
run(cmd: string, options?: RunOptions): Promise<CommandResult>
cmd
string
required
Shell command to execute
options
RunOptions
result
CommandResult
Example:
const result = await sandbox.commands.run('ls -la /home/user');
console.log(result.stdout);
console.log('Exit code:', result.exitCode);

// With streaming
await sandbox.commands.run('npm install', {
  cwd: '/home/user/project',
  onStdout: (data) => console.log('OUT:', data),
  onStderr: (data) => console.error('ERR:', data)
});

// With stdin
const result = await sandbox.commands.run('cat', {
  stdin: 'Hello, World!'
});

register()

Register a custom command.
register(name: string, handler: Command): void
See CommandRegistry for details.

SandboxFs Interface

The fs property provides promise-based filesystem operations.

readFile()

Read file contents.
readFile(path: string): Promise<string>
readFile(path: string, encoding: null): Promise<Uint8Array>
path
string
required
File path to read
encoding
null
If null, returns binary data
content
string | Uint8Array
File contents (string by default, Uint8Array if encoding is null)
Example:
const text = await sandbox.fs.readFile('/home/user/data.txt');
const binary = await sandbox.fs.readFile('/home/user/image.png', null);

writeFile()

Write file contents.
writeFile(path: string, content: string | Uint8Array): Promise<void>
path
string
required
File path to write
content
string | Uint8Array
required
File content to write
Example:
await sandbox.fs.writeFile('/home/user/output.txt', 'Hello, World!');
await sandbox.fs.writeFile('/home/user/data.bin', new Uint8Array([1, 2, 3]));

readdir()

List directory contents.
readdir(path: string): Promise<Array<{ name: string; type: 'file' | 'directory' }>>
path
string
required
Directory path to list
entries
Dirent[]
Array of directory entries
Example:
const entries = await sandbox.fs.readdir('/home/user');
for (const entry of entries) {
  console.log(entry.name, entry.type);
}

stat()

Get file or directory metadata.
stat(path: string): Promise<{ type: 'file' | 'directory'; size: number; mtime: number }>
path
string
required
Path to stat
stat
Stat
File metadata
Example:
const stat = await sandbox.fs.stat('/home/user/data.txt');
console.log('Size:', stat.size, 'bytes');
console.log('Modified:', new Date(stat.mtime));

mkdir()

Create a directory.
mkdir(path: string, options?: { recursive?: boolean }): Promise<void>
path
string
required
Directory path to create
options
object
Example:
await sandbox.fs.mkdir('/home/user/projects/my-app', { recursive: true });

rm()

Remove a file or directory.
rm(path: string, options?: { recursive?: boolean }): Promise<void>
path
string
required
Path to remove
options
object
Example:
await sandbox.fs.rm('/home/user/temp.txt');
await sandbox.fs.rm('/home/user/old-project', { recursive: true });

exists()

Check if a path exists.
exists(path: string): Promise<boolean>
path
string
required
Path to check
exists
boolean
True if the path exists
Example:
if (await sandbox.fs.exists('/home/user/config.json')) {
  // Load config
}

rename()

Rename or move a file or directory.
rename(oldPath: string, newPath: string): Promise<void>
oldPath
string
required
Current path
newPath
string
required
New path
Example:
await sandbox.fs.rename('/home/user/old.txt', '/home/user/new.txt');

cp()

Copy a file.
cp(src: string, dest: string): Promise<void>
src
string
required
Source file path
dest
string
required
Destination file path
Example:
await sandbox.fs.cp('/home/user/original.txt', '/home/user/copy.txt');

writeFiles()

Write multiple files atomically.
writeFiles(files: Array<{ path: string; content: string | Uint8Array }>): Promise<void>
files
FileEntry[]
required
Array of files to write
Example:
await sandbox.fs.writeFiles([
  { path: '/home/user/index.html', content: '<h1>Hello</h1>' },
  { path: '/home/user/style.css', content: 'body { margin: 0; }' },
  { path: '/home/user/script.js', content: 'console.log("Hi");' }
]);

Type Definitions

interface SandboxOptions {
  persist?: boolean;
  env?: Record<string, string>;
  cwd?: string;
  files?: Record<string, string | Uint8Array>;
  terminal?: ITerminal;
  mounts?: Array<{
    virtualPath: string;
    hostPath: string;
    readOnly?: boolean;
    fsModule?: NativeFsModule;
  }>;
}

interface RunOptions {
  cwd?: string;
  env?: Record<string, string>;
  signal?: AbortSignal;
  timeout?: number;
  onStdout?: (data: string) => void;
  onStderr?: (data: string) => void;
  stdin?: string;
}

interface CommandResult {
  stdout: string;
  stderr: string;
  exitCode: number;
}

Build docs developers (and LLMs) love