Files
bun.sh/docs/cli/run.md
Claude Bot 3c886c7ec8 Implement --workspace flag for bun run command
This adds npm-compatible --workspace functionality to bun run, allowing
users to run scripts in specific workspace packages.

Key features:
- Accepts --workspace/-w flag with package names
- Supports multiple --workspace flags
- Preserves workspace definition order (unlike --filter which uses dependency order)
- Can be combined with --filter flags
- Includes comprehensive test coverage

Example usage:
  bun run --workspace foo test
  bun run -w foo -w bar test
  bun run --workspace foo --filter 'ba*' test

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-07-14 12:50:03 +00:00

7.6 KiB
Raw Blame History

The bun CLI can be used to execute JavaScript/TypeScript files, package.json scripts, and executable packages.

Performance

Bun is designed to start fast and run fast.

Under the hood Bun uses the JavaScriptCore engine, which is developed by Apple for Safari. In most cases, the startup and running performance is faster than V8, the engine used by Node.js and Chromium-based browsers. Its transpiler and runtime are written in Zig, a modern, high-performance language. On Linux, this translates into startup times 4x faster than Node.js.

{% table %}


  • bun hello.js
  • 5.2ms

  • node hello.js
  • 25.1ms

{% /table %} {% caption content="Running a simple Hello World script on Linux" /%}

Run a file

{% callout %} Compare to node <file> {% /callout %}

Use bun run to execute a source file.

$ bun run index.js

Bun supports TypeScript and JSX out of the box. Every file is transpiled on the fly by Bun's fast native transpiler before being executed.

$ 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.

$ bun index.tsx
$ bun index.js

--watch

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

$ bun --watch run index.tsx

{% callout %} Note — 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

Flags that occur at the end of the command will be ignored and passed through to the "dev" script itself. {% /callout %}

Run a package.json script

{% note %} Compare to npm run <script> or yarn <script> {% /note %}

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

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

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

Use bun run <script> to execute these scripts.

$ 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 bun shell to support bash-like syntax and many common commands.

{% callout %} The startup time for npm run on Linux is roughly 170ms; with Bun it is 6ms. {% /callout %}

Scripts can also be run with the shorter command bun <script>, however if there is a built-in bun command with the same name, the built-in command takes precedence. In this case, use the more explicit bun run <script> command to execute your package script.

$ bun run dev

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

$ 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 will execute preclean and postclean, if defined. If the pre<script> fails, Bun will not execute 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.

#!/usr/bin/env node

// do stuff

By default, Bun respects this shebang and executes the script with node. However, you can override this behavior with the --bun flag. For Node.js-based CLIs, this will run the CLI with Bun instead of Node.js.

$ bun run --bun vite

Filtering

In monorepos containing multiple packages, you can use the --filter argument to execute scripts in many packages at once.

Use bun run --filter <name_pattern> <script> to execute <script> in all packages whose name matches <name_pattern>. For example, if you have subdirectories containing packages named foo, bar and baz, running

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

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

Find more details in the docs page for filter.

Workspaces

Similar to npm, you can use the --workspace argument to run scripts in specific workspace packages.

Use bun run --workspace <name> <script> to execute <script> in the workspace package named <name>.

bun run --workspace foo test

You can specify multiple workspaces by using the flag multiple times:

bun run --workspace foo --workspace bar test

Or use the short flag -w:

bun run -w foo -w bar test

Unlike --filter, the --workspace flag requires exact package name matches and executes scripts in the order they appear in your package.json workspaces configuration, not in dependency order.

You can also combine --workspace with --filter:

bun run --workspace foo --filter 'ba*' test

This will run the test script in both the foo workspace (exact match) and any packages matching ba* (pattern match).

bun run - to pipe code from stdin

bun run - lets you read JavaScript, TypeScript, TSX, or JSX from stdin and execute it without writing to a temporary file first.

$ 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:

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

For convenience, all code is treated as TypeScript with JSX support when using bun run -.

bun run --smol

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

$ bun --smol run index.tsx

This causes the garbage collector to run more frequently, which can slow down execution. However, it can be useful in environments with limited memory. Bun automatically 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, so this is mostly useful for cases where you want to make the heap size grow more slowly.

Resolution order

Absolute paths and paths starting with ./ or .\\ are always executed as source files. Unless using bun run, running a file with an allowed extension will prefer the file over a package.json script.

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

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

{% bunCLIUsage command="run" /%}