Bun 1.2 Replaced Node in Every New RAXXO Project
- Bun 1.2 installs dependencies in 3 seconds where Node took 38, across 17 RAXXO projects
- Built-in TypeScript, SQLite, test runner, and bundler removed 9 devDependencies from every new repo
- Test suite that took 11 seconds on Vitest now runs in 1.4 seconds on bun test
- Node still wins for long-lived production backends with native bindings and battle-tested modules
I rewrote the init scripts on all 17 RAXXO projects last month. Every new repo now starts with `bun init`. Node still runs some older backends, but nothing new in this studio touches npm anymore. Here is why the switch stuck, with the numbers that pushed me over.
The install times that changed my default
Every weekend I clone two or three RAXXO repos on the Neo machine to keep it in sync. Before Bun 1.2, the first thing that happened after `git clone` was a coffee break. Node plus npm chewed through 38 seconds on a medium React project, 71 seconds on the raxxo-shop tooling folder, 4 minutes on a Next.js monorepo with 1,200 packages.
Bun 1.2 landed with a rewritten install path that now uses a per-project binary lockfile and parallel network IO. Same React project: 3 seconds. Same shop tooling: 5 seconds. Same monorepo: 27 seconds.
The second install is even wilder. Bun's global cache stores unpacked packages once, then hardlinks them into node_modules. Switching branches and reinstalling used to take 20 seconds on npm. On Bun it is often 300 milliseconds. I started noticing the pause was gone, then I started noticing I stopped context-switching during installs, which meant I stayed in flow longer.
Multiply that across 17 projects, 5 working days, maybe 8 installs per day. That is 40 install events a day. Saving 30 seconds each gives back 20 minutes. Not life-changing, but the context-switch cost is the real saving. I stopped opening a second browser tab while waiting.
Lockfile behavior is also sharper. `bun.lockb` is a binary format, 4 to 6 times smaller than package-lock.json, and Bun is stricter about matching versions across machines. I have not had a "works on my laptop" install mismatch since January. Compare that to the npm lockfile debugging I used to do every other month, where a peer dep would resolve differently on macOS versus the Vercel build environment.
One runtime replaced nine devDependencies
This is the part I tell every solo dev who asks. Bun ships as one binary that does what a stack of npm packages used to do.
Out went ts-node, esbuild-register, and tsx. Bun runs TypeScript natively. `bun run script.ts` just works. No `ts-node --esm` flags, no `tsx watch`, no tsconfig paths hack. I deleted 3 devDependencies and 47 lines of configuration across the studio.
Out went Vitest and Jest for most repos. Bun has its own test runner with a Jest-compatible API. My raxxo-studio component tests moved across in 20 minutes, mostly renaming imports from `vitest` to `bun:test`. The test suite that took 11 seconds on Vitest now runs in 1.4 seconds.
Out went better-sqlite3 and the node-sqlite3 adapter for scripts. Bun has a native SQLite driver. `import { Database } from "bun:sqlite"` gives me a sync, fast, zero-config SQL layer. I use it for local dev databases in Git Dojo and for the blog sync tracker. No native build step, no Xcode prompt on a fresh laptop.
Out went ncc, tsup, and a Rollup config I never fully understood. `bun build` handles bundling for scripts, workers, and single-file binaries. The Blueprint packaging script that built a 52KB ZIP for distribution used to rely on 3 tools chained together. Now it is one `bun build --compile` line.
Count them: ts-node, tsx, Vitest, Jest, better-sqlite3, sqlite3, ncc, tsup, dotenv-cli. Nine fewer entries in package.json. Nine fewer version bumps to chase. Nine fewer configs to maintain.
The knock-on effects matter too. Fewer devDependencies means fewer Dependabot alerts. Fewer breaking changes when I finally update the toolchain. Fewer nights where I discover that my test runner and my bundler disagree about how to resolve a TypeScript path alias. The surface area of my own config has shrunk enough that I can reread a project's entire tooling setup in 5 minutes, which matters when I come back to something after a month away.
The workflow changes that actually matter
Speed numbers are easy to quote. The real shift is that Bun removed decision points from my day.
Loading environment variables is built in. `bun --env-file=.env run script.ts` or just put `.env` in the project root and Bun reads it. No `dotenv/config` import at the top of every file. I ripped out `dotenv` from 14 repos over one weekend.
The watch mode is native. `bun --watch run dev.ts` restarts on file change without nodemon. On the raxxo-shop sync scripts, this cut the restart loop from 800ms to 60ms. Enough of a difference that I stopped killing and rerunning processes manually.
Single-file binaries are real. `bun build --compile ./cli.ts --outfile=raxxo` produces a standalone executable. I ship the Git Dojo CLI this way now, 54MB including the runtime. No pkg, no nexe, no Docker image. Users who install Git Dojo do not need Node on their machine.
Shell scripting through `Bun.$` replaced half my bash one-liners. When I want to run a pipeline from inside TypeScript, I write `await $\`git log --oneline | head -5\`` and it behaves like you would hope. Cross-platform, escaped, typed. The blog syndication tracker migrated from a mix of bash and Node to a single TypeScript file using Bun.$ and it is 120 lines shorter.
The sum of all this: new projects start with `bun init` and a 6-line package.json. Dev, test, build, bundle, and SQLite are all handled by the runtime. My template repo dropped from 41 files to 19.
One more piece that quietly became load-bearing: Bun's HTTP server. `Bun.serve({ port: 3000, fetch })` gives me a fast server in 3 lines, using the standard Web `Request` and `Response` objects. I started prototyping small internal tools as Bun servers instead of reaching for Express or Fastify. The raxxo-studio dashboard worker that pulls analytics from 4 APIs used to be a tiny Fastify app. Now it is 80 lines of plain Bun, and it handles the same traffic with lower memory.
When I still reach for Node
Honesty check, because this would read like a sales pitch otherwise. Bun is not replacing Node everywhere in the studio.
Long-lived production backends that have been running for 2 or 3 years still run on Node. The high-traffic stuff needs the ecosystem maturity: PM2 with battle-tested restart logic, APM agents from New Relic and Datadog that have years of Node instrumentation, observability hooks that assume V8 internals. Bun is getting there, but Node is still the boring, safe choice for something that must not fall over at 3am.
Native modules with complex bindings are still a Node habitat. `canvas` works on Bun now, but the edge cases (Freetype on Linux Alpine, headless rendering pipelines) are better documented for Node. Same for sharp with certain platforms, and some image-processing libraries that lean on node-gyp in specific ways. If the dependency has a bindings.gyp file and a decade of Stack Overflow answers, Node is still where I stay.
Serverless platforms with deep Node tuning are a mixed bag. Vercel added Bun support, which is great for my setup, but the cold-start story on certain AWS Lambda configurations still favors Node. If a project is shipping to Lambda with tight cold-start budgets, I test both runtimes and pick by measurement, not vibes.
Tooling that assumes a Node global. Older scripts, some Electron builders, a few CI actions. These work on Bun most of the time, but when they do not, debugging the difference costs more than whatever speed I would have gained. For stable, boring projects I stay with the stable, boring runtime.
The honest summary: 85% of my new work is Bun, 15% stays on Node. The 15% is almost always about risk management, not performance.
Bottom line
Bun 1.2 replaced Node as the default for every new RAXXO project because it collapsed a stack of tools into one binary, and the install speed meant I stopped context-switching while waiting. Nine devDependencies gone. Test suites roughly 8 times faster. Single-file binaries shipping with no build pipeline underneath. The workflow change is the real story, not the speed.
Node keeps the older backends and the edge cases with native bindings. No runtime war here, just better tool selection per job. If you run 10 or more projects as a solo dev, try Bun on your next new repo. You probably will not go back for anything green-field.
I write about the RAXXO dev stack and the tools that shape it every week. The full lab archive is at raxxo.shop/blogs/lab, and the studio tools (Git Dojo, Blueprint, Statusline Builder) are built on the stack described here.
Back to all articles