Bun.spawn() stdin parameter values
The stdin parameter accepts: null (no input, default), "pipe" (returns FileSink for incremental writing), "inherit" (inherit parent stdin), Bun.file() (read from file), TypedArray or DataView (binary buffer), Response (use response body), Request (use request body), ReadableStream (readable stream), Blob, or number (file descriptor).
Bun.spawn() basic usage
Bun.spawn() accepts a command as an array of strings and returns a Bun.Subprocess object. Example: const proc = Bun.spawn(["bun", "--version"]); console.log(await proc.exited); // 0
Bun.spawn() parameters object options
The second argument to Bun.spawn is an options object that can include: cwd (working directory), env (environment variables), and onExit (exit handler callback). The onExit callback signature is: onExit(proc, exitCode, signalCode, error).
Subprocess.pid property
The Subprocess object has a pid property that returns the process ID of the subprocess.
Writing to subprocess stdin with pipe
When stdin is set to "pipe", the parent process can write to proc.stdin using proc.stdin.write() for both strings and binary data, proc.stdin.flush() to send buffered data, and proc.stdin.end() to close the input stream.
Bun.spawn() stdout and stderr parameter values
The stdout and stderr parameters accept: "pipe" (default for stdout, pipes to ReadableStream), "inherit" (default for stderr, inherit from parent), "ignore" (discard output), Bun.file() (write to file), or number (file descriptor).
Subprocess exit handling with exited property
The exited property is a Promise that resolves when the process exits. After the process exits, check: proc.killed (boolean), proc.exitCode (null | number), and proc.signalCode (null | "SIGABRT" | etc).
Killing a subprocess
Call proc.kill() with no arguments to kill with default signal, proc.kill(15) to specify a signal code by number, or proc.kill("SIGTERM") to specify a signal by name. The killed property becomes true after killing.
Subprocess.unref() for detaching from parent
The parent bun process does not terminate until all child processes have exited. Call proc.unref() to detach the child process from the parent, allowing the parent to exit.
Subprocess.resourceUsage() method
After a process exits, call proc.resourceUsage() to get an object with: maxRSS (max memory in bytes), cpuTime.user (user CPU time in microseconds), cpuTime.system (system CPU time in microseconds).
Bun.spawn() cgroup option for resource limits on Linux
On Linux, pass a cgroup option set to a directory path under /sys/fs/cgroup to start the subprocess inside a control group. The child joins the cgroup before executing, so limits on memory, pids, and CPU apply from the first instruction. Pass either a directory path or an open directory file descriptor.
Bun.spawn() AbortSignal support
Pass an AbortSignal via the signal option to abort a subprocess. Create an AbortController, pass controller.signal to spawn, then call controller.abort() to kill the process.
Bun.spawn() timeout and killSignal options
Set timeout (in milliseconds) to terminate a subprocess after a duration. By default, timed-out processes are killed with SIGTERM; specify a different signal with killSignal (string name or signal number). The killSignal option also controls which signal is sent when an AbortSignal is aborted.
Bun.spawnSync() maxBuffer option
For Bun.spawnSync, maxBuffer limits how many bytes of output the process can emit before Bun kills it. Bun stops reading as soon as the limit is passed, so the returned output can exceed maxBuffer only by the single read that passed it.
IPC between bun processes
Bun supports inter-process communication between bun processes. To receive messages, specify an ipc handler: ipc(message, childProc) {}. Send messages from parent with childProc.send(). Child process sends with process.send() and receives with process.on("message", message => {}).
IPC serialization option for bun processes
The serialization option controls IPC format: "advanced" (default) uses JSC serialize API supporting everything structuredClone supports, "json" uses JSON.stringify/parse. Advanced does not support transferring ownership of objects.
Disconnect IPC channel
Call childProc.disconnect() to disconnect the IPC channel from the parent process.
IPC between Bun and Node.js
To use IPC between a bun process and a Node.js process, set serialization: "json" in Bun.spawn because Node.js and Bun use different JavaScript engines with different object serialization formats.
Terminal (PTY) support in Bun.spawn()
Use the terminal option to spawn a subprocess with a pseudo-terminal (PTY) attached. The subprocess sees a real terminal, enabling colored output, cursor movement, and interactive prompts. When terminal option is provided, process.stdout.isTTY is true, stdin/stdout/stderr are connected to the terminal, proc.stdin/stdout/stderr return null (use proc.terminal instead).
Terminal options for Bun.spawn()
The terminal option accepts: cols (number of columns, default 80), rows (number of rows, default 24), name (terminal type for PTY, default "xterm-256color"), data (callback when data received: (terminal, data) => void), exit (callback when PTY closes, exitCode 0=EOF/1=error, not subprocess exit code), drain (callback when ready for more data).
Terminal methods in Bun.spawn()
The Terminal object has methods: write(string | BufferSource) to write data, resize(cols, rows) to resize, setRawMode(bool) to set raw mode, ref() to keep event loop alive, unref() to allow event loop to exit, close() to close the terminal.
Reusable Terminal with new Bun.Terminal()
Create a terminal independently with await using terminal = new Bun.Terminal({...}) to run multiple commands in sequence through the same terminal session. The terminal can be reused across multiple spawns by passing it to the terminal option. You control when to close with terminal.close(). The exit callback fires when you call terminal.close(), not when each subprocess exits.
Terminal platform differences
Bun.Terminal uses openpty() on Linux/macOS and ConPTY (CreatePseudoConsole) on Windows. On Windows: termios flags always read 0 and are no-ops, no echo without a child process, ConPTY re-encodes output to VT sequences (semantically equivalent but not byte-identical), input \r is not translated to \n, process.on('SIGWINCH') may not fire unless child reads stdin in raw mode, and terminal.close() may not terminate still-running child on Windows before 11 24H2.
Bun.spawnSync() basic usage
Bun.spawnSync is the blocking equivalent of Bun.spawn. It supports the same inputs and parameters and returns a SyncSubprocess object. The stdout and stderr properties are Buffers instead of ReadableStreams, and there is no stdin property. Example: const proc = Bun.spawnSync(["echo", "hello"]); console.log(proc.stdout.toString());
SyncSubprocess object properties
SyncSubprocess has properties: success (boolean, true if exit code is 0), stdout (Buffer or undefined), stderr (Buffer or undefined), exitCode (number), signalCode (string or undefined), exitedDueToTimeout (true if timed out), pid (process ID), and resourceUsage (ResourceUsage object).
Bun.spawn() and Bun.spawnSync() use posix_spawn(3)
Bun.spawn and Bun.spawnSync use posix_spawn(3) for spawning processes. Bun's spawnSync spawns processes approximately 60% faster than Node.js child_process module.
Bun.spawn() signature and overloads
Bun.spawn has two signatures: spawn(command: string[], options?: SpawnOptions.OptionsObject): Subprocess and spawn(options: { cmd: string[] } & SpawnOptions.OptionsObject): Subprocess. Bun.spawnSync has the same two signatures returning SyncSubprocess.
SpawnOptions.OptionsObject complete reference
SpawnOptions.OptionsObject properties: cwd (string), env (Record<string, string | undefined>), stdio (tuple [Writable, Readable, Readable]), stdin (Writable), stdout (Readable), stderr (Readable), onExit (callback), ipc (callback), serialization ("json" | "advanced"), windowsHide (boolean), windowsVerbatimArguments (boolean), argv0 (string), signal (AbortSignal), timeout (number), killSignal (string | number), maxBuffer (number), terminal (TerminalOptions).
Subprocess interface properties and methods
Subprocess extends AsyncDisposable and has properties: stdin (FileSink | number | undefined | null), stdout (ReadableStream | number | undefined | null), stderr (ReadableStream | number | undefined | null), readable (ReadableStream | number | undefined | null), terminal (Terminal | undefined), pid (number), exited (Promise<number>), exitCode (number | null), signalCode (NodeJS.Signals | null), killed (boolean). Methods: kill(exitCode?: number | NodeJS.Signals), ref(), unref(), send(message: any), disconnect(), resourceUsage(): ResourceUsage | undefined.
ResourceUsage interface details
ResourceUsage object contains: contextSwitches (voluntary and involuntary), cpuTime (user, system, total in microseconds), maxRSS (max resident set size in bytes), messages (sent and received), ops (in and out), shmSize, signalCount, swapCount.
Supported signal types in Bun.spawn()
Supported signal names: SIGABRT, SIGALRM, SIGBUS, SIGCHLD, SIGCONT, SIGFPE, SIGHUP, SIGILL, SIGINT, SIGIO, SIGIOT, SIGKILL, SIGPIPE, SIGPOLL, SIGPROF, SIGPWR, SIGQUIT, SIGSEGV, SIGSTKFLT, SIGSTOP, SIGSYS, SIGTERM, SIGTRAP, SIGTSTP, SIGTTIN, SIGTTOU, SIGUNUSED, SIGURG, SIGUSR1, SIGUSR2, SIGVTALRM, SIGWINCH, SIGXCPU, SIGXFSZ, SIGBREAK, SIGLOST, SIGINFO.