package.json, and prints Bun commands in its own output.
From Extension.js 4.1.21, the CLI runs on Bun too, from Bun 1.2 onward. The question below has two halves, and they now have different answers than they used to.
Can I use Bun instead of Node?
Yes, for your project and for the CLI process both.
Plain
bunx extension still runs the CLI on Node, because the published binary carries a #!/usr/bin/env node shebang. Add --bun, or set run.bun in bunfig.toml, to execute it on Bun instead.
Create a project with Bun
package.json pins the manager that you used:
package.json
Install and build
bun.lock file. Extension.js reads the lockfile on later runs to keep choosing Bun.
extension binary, so bun run dev, bun run build, and bun run preview all work.
Which Bun versions work
Extension.js needs Bun 1.2 or newer. The CLI readsprocess.versions.bun at startup and judges Bun on its own version, never on the Node version that Bun reports, because the two do not track each other. Bun 1.1.38 and Bun 1.2.0 both report Node 22.6.0, and only one of them finishes a build.
Below 1.2, Bun cannot load the rspack native binding, so an older Bun fails deep inside the bundler rather than at the door. The guard stops it first:
process.versions.bun, which the runtime sets itself, so every route into it is covered: the --bun flag on bunx and bun run, and a run.bun default in bunfig.toml.
How Extension.js detects Bun
Detection reads the project, not the command that you typed. Three signals feed it:- A
bun.lockorbun.lockblockfile at the project root. - A
packageManagerfield inpackage.jsonthat namesbun. - The
npm_config_user_agentenvironment variable that Bun sets when it runs a script.
npm, pnpm, yarn, bun, and deno. When no signal is present, it probes your PATH in the order pnpm, yarn, bun.
Automatic dependency installs
extension dev and extension build install missing dependencies before they compile. The install runs through the manager that was detected, and it passes --ignore-scripts. A postinstall script in a dependency therefore does not run during that step.
Caveats
- Bun-specific runtime APIs such as
Bun.filedo not belong in extension code. That code runs in the browser. - Extension.js writes no Bun-specific scripts. The
dev,build, andpreviewscripts are the same for every manager. - A template that you import through
extension createships without a lockfile. Extension.js stripsbun.lockandbun.lockbfrom it. Your own install then decides the tree.
Next steps
- Compare with the Deno setup.
- Learn how Extension.js handles Node APIs.
- Learn how to manage Extension configuration.

