Skip to main content
Bun Shell makes shell scripting with JavaScript and TypeScript ergonomic and safe. It is a cross-platform bash-like shell with seamless JavaScript interop — no extra dependencies required.

Features

Cross-platform

Works on Windows, Linux, and macOS. Common commands like ls, cd, rm are implemented natively — no cross-env or rimraf needed.

Safe by default

All interpolated values are treated as literal strings, preventing shell injection attacks.

JavaScript interop

Use Response, Blob, ArrayBuffer, Bun.file(), and other JS objects directly as stdin/stdout.

Familiar syntax

Supports redirection, pipes, globs, environment variables, and command substitution just like bash.

Basic usage

Run commands using the $ tagged template literal. By default, output goes to stdout:

Capturing output

Use .text() to capture stdout as a string:
Use .quiet() to suppress output without capturing it:

Capturing stdout and stderr as buffers

Awaiting a shell command directly returns an object with stdout and stderr as Buffers:

Other output formats


Error handling

By default, commands that exit with a non-zero code throw a ShellError:

Disabling throws

Use .nothrow() on a single command to check exitCode manually instead of catching:
Use $.nothrow() or $.throws(false) to change the default behavior for all commands:

Piping

Pipe the output of one command to another using |, just like in bash:
You can also pipe from JavaScript objects:

Redirection

Bun Shell supports all standard bash redirection operators, as well as redirecting to and from JavaScript objects.

Redirect to a JavaScript object

Supported targets: Buffer, typed arrays, ArrayBuffer, SharedArrayBuffer, Bun.file(path), Bun.file(fd).

Redirect from a JavaScript object

Supported sources: Buffer, typed arrays, ArrayBuffer, SharedArrayBuffer, Bun.file(), Response.

File redirection examples


Environment variables

Inline env vars

Set environment variables inline just like in bash:
Interpolated values are escaped automatically, preventing injection:

Per-command env with .env()

Override environment variables for a single command:

Global env with $.env()

Set default environment variables for all commands:

Working directory

Per-command .cwd()

Global $.cwd()


Command substitution

Use $(...) to insert the output of one command into another:
Use the $(...) syntax for command substitution. Due to how Bun uses the raw property on template literals, the backtick syntax (`...`) does not work for nested command substitution.

Builtin commands

Bun Shell ships native implementations of common commands for cross-platform compatibility: cd, ls, rm, echo, pwd, bun, cat, touch, mkdir, which, mv, exit, true, false, yes, seq, dirname, basename Any command not in this list is looked up in the system PATH.

Running .sh scripts

Use Bun to run .sh files directly. Bun Shell interprets them cross-platform:
script.sh
This also works on Windows:

Utilities

$.braces — brace expansion

$.escape — escape strings

To pass a raw (unescaped) string, wrap it in { raw: '...' }:

Security

Bun Shell does not invoke a system shell like /bin/sh. It is a re-implementation that treats all interpolated variables as single, literal strings, preventing command injection:
Spawning a new shell process bypasses Bun’s protections. If you use bash -c with interpolated user input, you are responsible for sanitizing that input:
Argument injection is not prevented. Bun passes strings as single arguments, but the target program may interpret them as its own flags:
Always validate and sanitize user-provided input before passing it to external commands.