Bun Runtime

Execute JavaScript/TypeScript files, package.json scripts, and executable packages with Bun's fast runtime.

The Bun Runtime is designed to start fast and run fast.

Bun uses the JavaScriptCore engine, developed by Apple for Safari. JavaScriptCore usually starts and runs faster than V8, the engine used by Node.js and Chromium-based browsers. Bun's transpiler and runtime are written in Rust. On Linux, Bun starts 4x faster than Node.js.

CommandTime
bun hello.js5.2ms
node hello.js25.1ms

The benchmark runs a Hello World script on Linux.

Run a file#

Use bun run to execute a source file.

terminal
bun run index.js

Bun supports TypeScript and JSX with no configuration. Bun transpiles every file on the fly with its native transpiler before running it.

terminal
bun run index.js
bun run index.jsx
bun run index.ts
bun run index.tsx

Alternatively, you can omit the run keyword and use the "naked" command; it behaves identically.

terminal
bun index.tsx
bun index.js

--watch#

To run a file in watch mode, use the --watch flag.

terminal
bun --watch run index.tsx

When using bun run, put Bun flags like --watch immediately after bun.

bun --watch run dev # ✔️ do this
bun run dev --watch # ❌ don't do this

bun ignores flags at the end of the command and passes them through to the "dev" script itself.

Run a package.json script#

Compare to npm run <script> or yarn <script>

bun [bun flags] run <script> [script flags]

Your package.json can define named "scripts" that correspond to shell commands.

package.json
{
  // ... other fields
  "scripts": {
    "clean": "rm -rf dist && echo 'Done.'",
    "dev": "bun server.ts"
  }
}

Use bun run <script> to execute these scripts.

terminal
bun run clean
rm -rf dist && echo 'Done.'
Cleaning...
Done.

Bun executes the script command in a subshell. On Linux & macOS, it checks for the following shells in order, using the first one it finds: bash, sh, zsh. On Windows, it uses the Bun Shell to support bash-like syntax and many common commands.

⚡️ The startup time for npm run on Linux is roughly 170ms; with Bun it is 6ms.

You can also run scripts with the shorter command bun <script>. If a built-in bun command has the same name, the built-in command takes precedence; use the explicit bun run <script> to run your package script instead.

terminal
bun run dev

To see a list of available scripts, run bun run without any arguments.

terminal
bun run
quickstart scripts:

 bun run clean
   rm -rf dist && echo 'Done.'

 bun run dev
   bun server.ts

2 scripts

Bun respects lifecycle hooks. For instance, bun run clean runs preclean and postclean, if defined. If the pre<script> fails, Bun does not run the script itself.

--bun#

It's common for package.json scripts to reference locally-installed CLIs like vite or next. These CLIs are often JavaScript files marked with a shebang to indicate that they should be executed with node.

cli.js
#!/usr/bin/env node

// do stuff

By default, Bun respects this shebang and executes the script with node. The --bun flag overrides it: the CLI runs with Bun instead of Node.js.

terminal
bun run --bun vite

Filtering#

In a monorepo, the --filter argument runs a script in many packages at once.

bun run --filter <pattern> <script> executes <script> in every package selected by <pattern>. The pattern can be a package name glob, a ./path, a {dir} directory or a dependency relation like foo.... For example, if you have subdirectories containing packages named foo, bar and baz, running

terminal
bun run --filter 'ba*' <script>

executes <script> in both bar and baz, but not in foo.

See --filter.

bun run - to pipe code from stdin#

bun run - reads JavaScript, TypeScript, TSX, or JSX from stdin and executes it without writing to a temporary file first.

terminal
echo "console.log('Hello')" | bun run -
Hello

You can also use bun run - to redirect files into Bun. For example, to run a .js file as if it were a .ts file:

terminal
echo "console.log!('This is TypeScript!' as any)" > secretly-typescript.js
bun run - < secretly-typescript.js
This is TypeScript!

bun run - treats all input as TypeScript with JSX support.

bun run --console-depth#

Control the depth of object inspection in console output with the --console-depth flag.

terminal
bun --console-depth 5 run index.tsx

--console-depth sets how deeply Bun displays nested objects in console.log() output. The default depth is 2. Higher values show more nested properties but may produce verbose output for complex objects.

console.ts
const nested = { a: { b: { c: { d: "deep" } } } };
console.log(nested);
// With --console-depth 2 (default): { a: { b: { c: [Object] } } }
// With --console-depth 4: { a: { b: { c: { d: 'deep' } } } }

bun run --smol#

In memory-constrained environments, use the --smol flag to reduce memory usage at a cost to performance.

terminal
bun --smol run index.tsx

--smol makes the garbage collector run more frequently, which can slow down execution. Bun adjusts the garbage collector's heap size based on the available memory (accounting for cgroups and other memory limits) with and without the --smol flag. The flag is therefore mostly useful when you want the heap to grow more slowly.

Resolution order#

Bun always executes absolute paths and paths starting with ./ or .\\ as source files. Unless you use bun run, a name with an allowed extension resolves to the file rather than a package.json script.

When a package.json script and a file have the same name, bun run prefers the script. The full resolution order is:

  1. package.json scripts: bun run build
  2. Source files: bun run src/main.js
  3. Binaries from project packages: bun add eslint && bun run eslint
  4. (bun run only) System commands: bun run ls

CLI Usage#

bun run <file or script>

General Execution Options#

--silentboolean

Don't print the script command

--if-presentboolean

Exit without an error if the entrypoint does not exist

--evalstring

Evaluate argument as a script. Alias: -e

--printstring

Evaluate argument as a script and print the result. Alias: -p

--helpboolean

Display this menu and exit. Alias: -h

Workspace Management#

--elide-linesnumberdefault:10

Number of lines of script output shown when using --filter (default: 10). Set to 0 to show all lines

--filterstring

Run a script in all workspace packages matching the pattern. Alias: -F

--workspacesboolean

Run a script in all workspace packages (from the workspaces field in package.json)

--parallelboolean

Run multiple scripts or workspace scripts concurrently with prefixed output

--sequentialboolean

Run multiple scripts or workspace scripts one after another with prefixed output

--no-exit-on-errorboolean

When using --parallel or --sequential, continue running other scripts when one fails

Runtime & Process Control#

--bunboolean

Force a script or package to use Bun's runtime instead of Node.js (via symlinking node). Alias: -b

--shellstring

Control the shell used for package.json scripts. Supports either bun or system

--interactiveboolean

Open the Node.js-compatible REPL (node:repl). When combined with -e, starts the REPL and then evaluates the script. Under --interactive, -e is raw JavaScript (matching node -i -e). Use bun repl for TypeScript. Distinct from bun repl, which is Bun's native REPL.

--smolboolean

Use less memory, but run garbage collection more often

--expose-gcboolean

Expose gc() on the global object. Has no effect on Bun.gc()

--no-deprecationboolean

Suppress all reporting of the custom deprecation

--throw-deprecationboolean

Determine whether deprecation warnings result in errors

--titlestring

Set the process title

--zero-fill-buffersboolean

Force Buffer.allocUnsafe(size) to be zero-filled

--no-addonsboolean

Throw an error if process.dlopen is called, and disable export condition node-addons

--unhandled-rejectionsstring

One of strict, throw, warn, none, or warn-with-error-code

--console-depthnumberdefault:2

Set the default depth for console.log object inspection (default: 2)

Development Workflow#

--watchboolean

Automatically restart the process on file change

--watch-kill-signalstringdefault:SIGTERM

Signal whose handlers run when --watch restarts the process

--hotboolean

Enable auto reload in the Bun runtime, test runner, or bundler

--no-clear-screenboolean

Disable clearing the terminal screen on reload when --hot or --watch is enabled

Debugging#

--inspectstring

Activate Bun's debugger

--inspect-waitstring

Activate Bun's debugger, wait for a connection before executing

--inspect-brkstring

Activate Bun's debugger, set breakpoint on first line of code and wait

Dependency & Module Resolution#

--preloadstring

Import a module before Bun loads other modules. Alias: -r

--requirestring

Alias of --preload, for Node.js compatibility

--importstring

Alias of --preload, for Node.js compatibility

--no-installboolean

Disable auto install in the Bun runtime

--installstringdefault:auto

Configure auto-install behavior. One of auto (default, auto-installs when no node_modules), fallback (missing packages only), force (always)

-iboolean

Auto-install dependencies during execution. Equivalent to --install=fallback

--prefer-offlineboolean

Skip staleness checks for packages in the Bun runtime and resolve from disk

--prefer-latestboolean

Use the latest matching versions of packages in the Bun runtime, always checking npm

--conditionsstring

Pass custom conditions to resolve

--main-fieldsstring

Main fields to lookup in package.json. Defaults to --target dependent

--extension-orderstringdefault:.tsx,.ts,.jsx,.js,.json

Defaults to: .tsx,.ts,.jsx,.js,.json

Transpilation & Language Features#

--tsconfig-overridestring

Specify custom tsconfig.json. Default $cwd/tsconfig.json

--definestring

Substitute K:V while parsing, e.g. --define process.env.NODE_ENV:"development". Bun parses values as JSON. Alias: -d

--dropstring

Remove function calls, e.g. --drop=console removes all console.* calls

--loaderstring

Parse files with .ext:loader, e.g. --loader .js:jsx. Valid loaders: js, jsx, ts, tsx, json, toml, text, file, wasm, napi. Alias: -l

--no-macrosboolean

Disable macro execution in the bundler, transpiler and runtime

--jsx-factorystring

Changes the function called when compiling JSX elements using the classic JSX runtime

--jsx-fragmentstring

Changes the function called when compiling JSX fragments

--jsx-import-sourcestringdefault:react

Declares the module specifier used to import the jsx and jsxs factory functions. Default: react

--jsx-runtimestringdefault:automatic

automatic (default) or classic

--jsx-side-effectsboolean

Treat JSX elements as having side effects (disable pure annotations)

--ignore-dce-annotationsboolean

Ignore tree-shaking annotations such as @PURE

Networking & Security#

--portnumber

Set the default port for Bun.serve

--fetch-preconnectstring

Preconnect to a URL while code is loading

--max-http-header-sizenumberdefault:16384

Set the maximum size of HTTP headers in bytes. Default is 16KiB

--dns-result-orderstringdefault:verbatim

Set the default order of DNS lookup results. Valid orders: verbatim (default), ipv4first, ipv6first

--use-system-caboolean

Use the system's trusted certificate authorities

--use-openssl-caboolean

Use OpenSSL's default CA store

--use-bundled-caboolean

Use bundled CA store

--redis-preconnectboolean

Preconnect to $REDIS_URL at startup

--sql-preconnectboolean

Preconnect to PostgreSQL at startup

--user-agentstring

Set the default User-Agent header for HTTP requests

Global Configuration & Context#

--env-filestring

Load environment variables from the specified file(s)

--cwdstring

Absolute path to resolve files & entrypoints from. This only changes the process' cwd

--configstring

Specify path to Bun config file. Default $cwd/bunfig.toml. Alias: -c

Examples#

Run a JavaScript or TypeScript file:

bun run ./index.js
bun run ./index.tsx

Run a package.json script:

bun run dev
bun run lint