# 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:

```ts
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:

```ts
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:

```ts
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:

```ts
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](/docs/sdk/services-and-observability) when a named process should keep running independently of the caller.
