Comprehensive process spawning, shell scripting, and subprocess management with cross-platform compatibility, I/O control, and performance optimization.
Spawn child processes asynchronously with comprehensive I/O control and environment management.
/**
* Spawn a child process asynchronously
* @param command - Command array [program, ...args]
* @param options - Spawn options for I/O, environment, etc.
* @returns Subprocess instance
*/
function Bun.spawn(
command: string[],
options?: Bun.SpawnOptions
): Subprocess;
interface Bun.SpawnOptions {
/** Current working directory */
cwd?: string;
/** Environment variables (defaults to process.env) */
env?: Record<string, string>;
/** Standard input handling */
stdin?: "pipe" | "inherit" | "ignore" | number | ReadableStream | BunFile;
/** Standard output handling */
stdout?: "pipe" | "inherit" | "ignore" | number | WritableStream | BunFile;
/** Standard error handling */
stderr?: "pipe" | "inherit" | "ignore" | number | WritableStream | BunFile;
/** Detach the child process */
detached?: boolean;
/** Windows-specific: don't create a console window */
windowsHide?: boolean;
/** Signal to send on timeout */
killSignal?: string | number;
/** Timeout in milliseconds */
timeout?: number;
}Usage Examples:
// Simple command execution
const proc = Bun.spawn(["echo", "Hello, World!"]);
console.log(await new Response(proc.stdout).text()); // "Hello, World!\n"
// With options
const proc2 = Bun.spawn(["ls", "-la"], {
cwd: "/tmp",
stdout: "pipe",
stderr: "pipe"
});
// Process output streams
const output = await new Response(proc2.stdout).text();
const errors = await new Response(proc2.stderr).text();
// Interactive process with stdin
const proc3 = Bun.spawn(["cat"], {
stdin: "pipe",
stdout: "pipe"
});
// Write to stdin
proc3.stdin.getWriter().write(new TextEncoder().encode("Hello\n"));Spawn child processes synchronously and wait for completion.
/**
* Spawn a child process synchronously and wait for completion
* @param command - Command array [program, ...args]
* @param options - Spawn options
* @returns Synchronous subprocess result
*/
function Bun.spawnSync(
command: string[],
options?: Bun.SpawnOptions
): Bun.SyncSubprocess;
interface Bun.SyncSubprocess {
/** Exit code of the process */
exitCode: number | null;
/** Signal that terminated the process */
signalCode: string | null;
/** Standard output as Buffer */
stdout: Buffer;
/** Standard error as Buffer */
stderr: Buffer;
/** Whether the process succeeded (exitCode === 0) */
success: boolean;
}Usage Examples:
// Simple synchronous execution
const result = Bun.spawnSync(["echo", "Hello"]);
console.log("Exit code:", result.exitCode);
console.log("Output:", result.stdout.toString());
// Handle errors
const result2 = Bun.spawnSync(["nonexistent-command"]);
if (!result2.success) {
console.error("Command failed:", result2.stderr.toString());
}
// With timeout
const result3 = Bun.spawnSync(["sleep", "10"], {
timeout: 1000 // 1 second timeout
});Represents a running child process with methods for interaction and control.
interface Subprocess {
/** Process ID */
readonly pid: number;
/** Exit code (null while running) */
readonly exitCode: number | null;
/** Signal that killed the process */
readonly signalCode: string | null;
/** Whether process has exited */
readonly killed: boolean;
/** Standard input stream */
readonly stdin: WritableStream<Uint8Array>;
/** Standard output stream */
readonly stdout: ReadableStream<Uint8Array>;
/** Standard error stream */
readonly stderr: ReadableStream<Uint8Array>;
/**
* Wait for process to exit
* @returns Promise resolving to exit code
*/
exited: Promise<number>;
/**
* Kill the process
* @param signal - Signal to send (default: SIGTERM)
* @returns Whether the signal was sent successfully
*/
kill(signal?: string | number): boolean;
/**
* Get a reference to keep the process alive
* @returns Disposable reference
*/
ref(): void;
/**
* Remove reference to allow process exit
* @returns Void
*/
unref(): void;
}Usage Examples:
const proc = Bun.spawn(["long-running-command"]);
console.log("Process ID:", proc.pid);
// Kill after 5 seconds
setTimeout(() => {
proc.kill("SIGKILL");
}, 5000);
// Wait for exit
const exitCode = await proc.exited;
console.log("Process exited with code:", exitCode);
// Check if process was killed
if (proc.killed) {
console.log("Process was terminated by signal:", proc.signalCode);
}Cross-platform shell scripting with template literals, piping, and environment variable interpolation.
/**
* Execute shell commands using template literals
* @param template - Template string array
* @param expressions - Template expressions
* @returns Promise resolving to shell output
*/
function Bun.$(
template: TemplateStringsArray,
...expressions: any[]
): Promise<ShellOutput>;
interface ShellOutput {
/** Exit code */
readonly exitCode: number;
/** Standard output as text */
readonly stdout: string;
/** Standard error as text */
readonly stderr: string;
/** Combined stdout and stderr */
readonly text: string;
/** Output as JSON (parses stdout) */
json<T = any>(): T;
/** Output as lines array */
lines(): string[];
/** Whether command succeeded */
readonly success: boolean;
}Usage Examples:
// Basic shell command
const output = await Bun.$`echo "Hello, World!"`;
console.log(output.stdout); // "Hello, World!\n"
// Variable interpolation
const filename = "test.txt";
const result = await Bun.$`cat ${filename}`;
// Piping commands
const sorted = await Bun.$`ls -la | sort | head -5`;
console.log(sorted.lines());
// Environment variables
const path = await Bun.$`echo $HOME`;
// JSON output
const packageInfo = await Bun.$`cat package.json`;
const pkg = packageInfo.json();
// Error handling
const result2 = await Bun.$`nonexistent-command`;
if (!result2.success) {
console.error("Error:", result2.stderr);
}Utility functions for finding executables and process management.
/**
* Find executable in PATH
* @param command - Command name to find
* @param options - Search options
* @returns Full path to executable or null if not found
*/
function Bun.which(
command: string,
options?: WhichOptions
): string | null;
interface WhichOptions {
/** Additional paths to search */
PATH?: string;
/** Current working directory */
cwd?: string;
}Usage Examples:
// Find git executable
const gitPath = Bun.which("git");
console.log("Git found at:", gitPath);
// Custom PATH search
const pythonPath = Bun.which("python3", {
PATH: "/usr/local/bin:/usr/bin"
});
// Check if command exists
const hasDocker = Bun.which("docker") !== null;Access and manipulate environment variables through the Bun.env interface.
/** Environment variables with Node.js compatibility */
declare const Bun.env: Bun.Env & NodeJS.ProcessEnv;
interface Bun.Env extends Record<string, string | undefined> {
/** Get environment variable with optional default */
get(key: string, defaultValue?: string): string | undefined;
/** Set environment variable */
set(key: string, value: string): void;
/** Check if environment variable exists */
has(key: string): boolean;
/** Delete environment variable */
delete(key: string): boolean;
/** Get all environment variables as object */
toObject(): Record<string, string>;
}Usage Examples:
// Access environment variables
const nodeEnv = Bun.env.NODE_ENV || "development";
const port = parseInt(Bun.env.PORT || "3000");
// Set environment variables
Bun.env.set("DEBUG", "true");
// Check existence
if (Bun.env.has("API_KEY")) {
console.log("API key is configured");
}
// Use in spawned processes
const proc = Bun.spawn(["node", "script.js"], {
env: {
...Bun.env.toObject(),
CUSTOM_VAR: "value"
}
});/** Signal types for process termination */
type Signal =
| "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";
/** Standard I/O redirection options */
type StdioOption = "pipe" | "inherit" | "ignore" | number | ReadableStream | WritableStream | BunFile;
/** Process error with additional context */
interface ProcessError extends Error {
code?: string;
errno?: number;
syscall?: string;
path?: string;
spawnargs?: string[];
}