Commands and processes
Sandboxes support one-shot commands, streaming non-interactive processes, and TTY terminals. Choose the smallest process model that fits the work.
Run a command and wait
Use exec() when only the completed result matters:
const result = await sandbox.exec('php artisan test');
if (result.exitCode !== 0) {
throw new Error(result.stderr || result.output);
}
console.log(result.stdout);
The result contains ordered output, separate standard output and error text, and an exit code. Runtime and transport failures reject the promise, while a command's non-zero exit remains explicit result data for the caller to interpret.
Prefer the command-and-arguments overload when values come from outside your application. It avoids building a shell command string:
const result = await sandbox.exec('php', [
'artisan',
'route:list',
'--path=/api',
]);
Stream a process
Use run() when output must be handled before the process exits:
const process = sandbox.run('php artisan test', { tty: false });
const decoder = new TextDecoder();
for await (const chunk of process.output) {
console.log(chunk.source, decoder.decode(chunk.data));
}
const result = await process.wait();
if (result.exitCode !== 0) {
throw new Error(result.stderr || result.output);
}
The process handle also exposes stdout, stderr, stdin, and kill().
Open an interactive terminal
Use a terminal for TTY-oriented tools, prompts, or a user-facing shell:
const terminal = await sandbox.terminals.create({
command: 'bash',
size: [120, 32],
});
const reader = terminal.output.getReader();
const writer = terminal.input.getWriter();
await writer.write('echo ready\n');
const output = await reader.read();
console.log(output.value);
await terminal.kill();
Terminals and live process streams require realtime. Use a REST client for buffered runtime actions that have an HTTP mapping.
Use Services and observability when a named process should keep running independently of the caller.