interface
Spawn.BaseOptions
interface BaseOptions<In extends Writable, Out extends Readable, Err extends Readable>
- argv0?: string
Path to the executable to run in the subprocess.
Use this to wrap another application or to simulate a symlink.
- cgroup?: string | number
Start the child process inside this control group.
Pass the path of an existing cgroup directory (e.g.
"/sys/fs/cgroup/my-jobs"), or an open file descriptor for one. The child joins it before it begins executing, so resource limits configured on the cgroup (memory.max,pids.max, …) apply from its first instruction and to everything it spawns in turn. Works with both cgroup v1 and v2 hierarchies.Bun does not create or configure the cgroup; do that with
node:fsbeforehand.Linux only; ignored on other platforms. On Linux, the spawn fails if the cgroup cannot be joined (e.g. the directory does not exist).
import { mkdirSync, writeFileSync } from "node:fs"; const dir = "/sys/fs/cgroup/build-jobs"; mkdirSync(dir, { recursive: true }); writeFileSync(dir + "/memory.max", String(2 * 1024 ** 3)); Bun.spawn({ cmd: ["make"], cgroup: dir }); - detached?: boolean
Run the child in a separate process group, detached from the parent.
- POSIX: calls
setsid()so the child starts a new session and becomes the process group leader. It can outlive the parent and receive signals independently of the parent’s terminal/process group. - Windows: sets
UV_PROCESS_DETACHED, allowing the child to outlive the parent and receive signals independently.
Note: stdio may keep the parent process alive. Pass
stdio: ["ignore", "ignore", "ignore"]to the spawn constructor to prevent this. - POSIX: calls
- env?: Record<string, undefined | string>
The environment variables of the process
Defaults to
process.envas it was when the current Bun process launched.Changes to
process.envat runtime won't automatically be reflected in the default value. For that, you can passprocess.envexplicitly. - gid?: number
Sets the group identity of the child process (see setgid(2)).
POSIX only. On Windows the spawn fails with
ENOTSUP. - killSignal?: string | number
The signal to use when killing the process after a timeout, when the AbortSignal is aborted, or when the process goes over the
maxBufferlimit.// Kill the process with SIGKILL after 5 seconds const subprocess = Bun.spawn({ cmd: ["sleep", "10"], timeout: 5000, killSignal: "SIGKILL", }); - maxBuffer?: number
The maximum number of bytes the process may output. If the process goes over this limit, it is killed with signal
killSignal(defaults to SIGTERM). - serialization?: 'json' | 'advanced'
The serialization format to use for IPC messages. Defaults to
"advanced".To communicate with Node.js processes, use
"json".When
ipcis not specified, this is ignored. - signal?: AbortSignal
An AbortSignal that kills the subprocess when aborted.
Use this to abort the subprocess when another part of the program is aborted, such as a
fetch.If the signal is already aborted when
spawnis called, no process is created and anAbortError(withcauseset tosignal.reason) is thrown synchronously.If the signal is aborted after the process starts, the process is killed with the signal specified by
killSignal(defaults to SIGTERM).const controller = new AbortController(); const { signal } = controller; const start = performance.now(); const subprocess = Bun.spawn({ cmd: ["sleep", "100"], signal, }); await Bun.sleep(1); controller.abort(); await subprocess.exited; const end = performance.now(); console.log(end - start); // 1ms instead of 101ms - stderr?: Err
The file descriptor for the standard error. It may be:
"pipe",undefined: The process has a ReadableStream for standard output/error"ignore",null: The process has no standard output/error"inherit": The process inherits the standard output/error of the current processArrayBufferView: The process writes to the preallocated buffer. Not implemented.number: The process writes to the file descriptor
- stdin?: In
The file descriptor for the standard input. It may be:
"ignore",null,undefined: The process has no standard input"pipe": The process has a new FileSink for standard input"inherit": The process inherits the standard input of the current processArrayBufferView,Blob: The process reads from the buffernumber: The process reads from the file descriptor
- stdio?: [In, Out, Err, ...Readable | 'socket-fd'[]]
The standard file descriptors of the process, in the form [stdin, stdout, stderr]. This overrides the
stdin,stdout, andstderrproperties.For stdin you may pass:
"ignore",null,undefined: The process has no standard input (default)"pipe": The process has a new FileSink for standard input"inherit": The process inherits the standard input of the current processArrayBufferView,Blob,Bun.file(),Response,Request: The process reads from buffer/stream.number: The process reads from the file descriptor
For stdout and stderr you may pass:
"pipe",undefined: The process has a ReadableStream for standard output/error"ignore",null: The process has no standard output/error"inherit": The process inherits the standard output/error of the current processArrayBufferView: The process writes to the preallocated buffer. Not implemented.number: The process writes to the file descriptor
At indices >= 3,
"socket-fd"(POSIX only) is also accepted: creates a socketpair like"pipe", but the parent-end fd exposed via Subprocess.stdio is owned by the caller and is never closed by the subprocess. Use this when you wrap the fd in something that will close it itself (e.g.net.connect({fd})). On Windows it behaves the same as"pipe". - stdout?: Out
The file descriptor for the standard output. It may be:
"pipe",undefined: The process has a ReadableStream for standard output/error"ignore",null: The process has no standard output/error"inherit": The process inherits the standard output/error of the current processArrayBufferView: The process writes to the preallocated buffer. Not implemented.number: The process writes to the file descriptor
- timeout?: number
The maximum amount of time the process is allowed to run in milliseconds.
If the timeout is reached, the process is killed with the signal specified by
killSignal(defaults to SIGTERM).// Kill the process after 5 seconds const subprocess = Bun.spawn({ cmd: ["sleep", "10"], timeout: 5000, }); await subprocess.exited; // Will resolve after 5 seconds - uid?: number
Sets the user identity of the child process (see setuid(2)).
POSIX only. On Windows the spawn fails with
ENOTSUP. - ipc(message: any,handle?: unknown): void;
When specified, Bun opens an IPC channel to the subprocess. The passed callback is called for incoming messages, and
subprocess.sendcan send messages to the subprocess. Messages are serialized using the JSC serialize API, which allows the same types thatpostMessage/structuredClonesupports.The subprocess can send and receive messages with
process.sendandprocess.on("message"), respectively. This is the same API that Node.js exposes whenchild_process.fork()is used.This is only compatible with processes that are other
buninstances.@param subprocessThe Subprocess that received the message
Called exactly once when the IPC channel between the parent and this subprocess is closed. After this runs, no further IPC messages will be delivered.
When it fires:
- The child called
process.disconnect()or the parent calledsubprocess.disconnect(). - The child exited for any reason (normal exit or due to a signal like
SIGILL,SIGKILL, etc.). - The child replaced itself with a program that does not support Bun IPC.
Notes:
- This callback indicates that the pipe is closed; it is not an error by itself. Use onExit or Subprocess.exited to determine why the process ended.
- It may occur before or after onExit depending on timing; do not rely on ordering. Typically, if you or the child call
disconnect()first, this fires before onExit; if the process exits without an explicit disconnect, either may happen first. - Only runs when ipc is enabled and runs at most once per subprocess.
- If the child becomes a zombie (exited but not yet reaped), the IPC is already closed, and this callback will fire (or may already have fired).
const subprocess = spawn({ cmd: ["echo", "hello"], ipc: (message) => console.log(message), onDisconnect: () => { console.log("IPC channel disconnected"); }, });- The child called
- exitCode: null | number,signalCode: null | number,): void | Promise<void>;
Callback that runs when the Subprocess exits
This is called even if the process exits with a non-zero exit code.
Warning: this may run before the
Bun.spawnfunction returns.An alternative is
await subprocess.exited.@param errorIf an error occurred in the call to waitpid2, this is the error.
const subprocess = spawn({ cmd: ["echo", "hello"], onExit: (subprocess, code) => { console.log(`Process exited with code ${code}`); }, });