Packages and scripts
Run package binaries with bunx
Use bunx to run package command-line tools without turning every temporary tool into a global installation.
Some npm packages provide command-line tools. Prettier formats code, tsc checks types, create-vite scaffolds a project. bunx finds and runs those tools for you.
For example, run Prettier without installing it globally:
bunx prettier --check .
bunx first looks for the executable in the project’s installed packages, inside node_modules/.bin. If it’s not there, Bun downloads the package into a shared cache and runs it from there. Nothing is added to your project.
This is the same idea as npx, and it fills the same role. The difference you notice is speed. Bun’s cache makes the second run of any tool close to instant.
You can pin a version when it matters:
bunx prettier@3 --check .
Prefer local versions for project tools
A formatter used by a team should have a version recorded by the project. Otherwise two people run bunx prettier on different days, get different releases, and format the same file two different ways. The diff is full of whitespace changes, and CI fails on a file nobody edited on purpose.
Install it as a development dependency instead:
bun add --dev prettier
Then add a script to package.json:
{
"scripts": {
"format": "prettier --write .",
"format:check": "prettier --check ."
}
}
Now everyone runs the same installed version:
bun run format:check
Here’s the rule I follow. Use bunx directly for one-off commands, project generators, and tools I’m evaluating. Use a local development dependency for any command that belongs to the project’s normal workflow, because the version then lives in bun.lock where it belongs.
Choose the runtime deliberately
Many package binaries start with a Node.js shebang, the #!/usr/bin/env node line at the top of the file. bunx respects it and runs the tool with Node.js when Node is installed.
You can force Bun with --bun:
bunx --bun vite --version
Do this only when you intend to test the tool under Bun. And be careful with the opposite conclusion. A command working through ordinary bunx does not prove the package runs on the Bun runtime, because it may have run on Node the whole time.
Lesson completed