Nub vs Vite+: Two Rust Toolchains for Opposite Ends of the JS Stack
Nub and Vite+ are both 2026 oxc-powered Rust toolchains that look like rivals but are not. A senior engineer's rule for which binary belongs in which repo.
The JavaScript toolchain is still a stack of separate parts: a package manager, a runtime, a TypeScript runner, a bundler, a test runner, a linter, and a formatter, each with its own config file and its own version drift. Two 2026 projects promise to collapse that pile into one fast Rust binary: Nub and Vite+. Both are oxc-powered, single-binary, and shipped weeks apart, so engineers keep filing them as rivals. They are not. Vite+ owns the browser-facing application pipeline; Nub owns the stock-Node process. The rule is that simple: if your build output loads in a browser, standardize on Vite+; if it runs as a Node process, reach for Nub. The numbers below are vendor micro-benchmarks on specific scenarios, not independent measurements.
What Vite+ owns
Vite+ is a single vp command that unifies the web-development workflow. It reached beta on July 2, 2026 (the alpha was March 13, 2026). The command surface covers the whole browser-facing pipeline:
vp dev # HMR dev server on Vite 8
vp check # Oxlint + Oxfmt + type check in one pass
vp test # Vitest
vp build # production build (Rolldown)
vp pack # bundle a library (tsdown)
vp run build # monorepo-aware task runner with caching
Under the hood it bundles Vite, Vitest, Rolldown, tsdown, Oxlint, and Oxfmt behind that one binary, and it also manages the runtime and the package manager. It is fully open source under MIT, and vp create and vp migrate handle scaffolding and moving an existing Vite project across.
The trade-off is coupling. You stop configuring six tools directly and start trusting one integrated stack. When an edge case shows up in a plugin or a framework, you debug through the abstraction instead of the tool. In practice vp migrate does most of a plain-Vite migration, but the guide is explicit that complex projects still need manual follow-up. The upside is depth: Vite 8, Rolldown, and Vitest are the ecosystem defaults, so the parts inside the binary are the parts most teams already ship.
What Nub owns
Nub is a Bun-like developer experience on top of stock node, written in Rust. The design stance is the opposite of a new runtime: it augments Node instead of replacing it. It ships as @nubjs/nub, launched in June 2026, and reached v0.4.x within weeks. The author is Colin McDonnell, the creator of Zod and formerly of Bun.
nub server.ts # run TypeScript on the Node the project pins
nub watch server.ts # same, on Node's built-in --watch
nub install # pnpm-compatible install, existing lockfiles work
nubx tsc --noEmit # run a bin without a global install
nub node 22 # version manager, replaces nvm/fnm/n/volta
The headline command is nub <file>. It transpiles TypeScript in memory via oxc, loads .env, resolves tsconfig path aliases, and then runs the result on the stock Node the project pins. That single command replaces node, tsx, ts-node, and dotenv-cli. Around it sit a script runner (nub run), a bin runner (nubx / nub dlx), a pnpm-compatible package manager (nub install), a watch mode built on Node’s own --watch, and a version manager (nub node) that stands in for nvm, fnm, n, and volta. The stated design goal is no new runtime, no vendor-specific API surface, and no lock-in; it stays compatible with existing npm, pnpm, and yarn lockfiles.
The trade-off is maturity, not lock-in. Nub is at v0.4.x and is effectively single-maintainer, though a credible one. Because it augments rather than replaces, the exit cost is close to zero: your lockfiles keep working, and removing it drops you back on node, tsx, and pnpm with no migration. The risk lives in early-stage bugs on the transpile-and-run path and in gaps against mature version managers, not in a runtime you cannot leave.
A fair objection here is why not just use Bun. Nub is Bun’s developer experience without Bun’s runtime bet: the same one-binary ergonomics, the opposite decision about what runs your code. Bun replaces the runtime. It runs on JavaScriptCore with its own transpiler and bundler, and its 2026 Rust rewrite, now under Anthropic, makes it another single fast Rust binary, but not an oxc one and not stock Node. Nub keeps the Node your production already runs and only augments it: oxc transpiles in memory, then the exact stock V8 you pin executes the result. That one difference is the whole reason to stay on stock Node. A service that must match a Node deployment’s runtime semantics, a native addon compiled against Node’s ABI, or a team that will not re-qualify a runtime just to gain a faster install all point back to Nub. If none of those bind you, the override stands: switch to Bun or Deno, and Nub solves a problem you no longer have.
The single slot where they overlap
Read the two command surfaces side by side and the confusion dissolves. They point in opposite directions almost everywhere.
| Capability | Vite+ | Nub |
|---|---|---|
| Browser dev server (HMR) | Yes (vp dev) | No |
| Production browser bundle | Yes (vp build) | No |
| Library bundling | Yes (vp pack) | No |
| Test runner | Yes (vp test) | No |
| Lint and format | Yes (vp check) | No |
| Monorepo task runner | Yes (vp run) | Partial (nub run dispatch) |
| Run backend TS on stock Node | No | Yes (nub <file>) |
| Package manager | Yes | Yes (nub install) |
| Runtime and version management | Yes | Yes (nub node) |
The only rows where both say yes are the last two: package manager and runtime or version management. That is the plumbing. Everything above it points up toward the browser artifact for Vite+ and down toward the Node process for Nub. So the only genuine collision is who owns the plumbing slot in a repo that has both a frontend and a backend. In a full-stack monorepo, let the more mature, ecosystem-backed option own the shared plumbing. Today that is Vite+, because it sits on Vite 8 and the broad Vite ecosystem and is now backed by Cloudflare. Nub then earns its place specifically for running and watching the backend and CLI TypeScript on stock Node.
Deciding from the artifact
Root the decision at the artifact you ship, not at the feature list. The feature lists overlap enough to mislead; the artifacts never do.
The default reads cleanly in two lines. When the output loads in a browser, Vite+ owns the toolchain. When the output is a Node process that must stay on stock Node, Nub owns run, watch, and install. The branches only exist to name the overrides: a willingness to switch runtime points to Bun or Deno instead of Nub, and an unacceptable pre-1.0 risk points back to the boring assembled stack on either side.
Reading the vendor numbers honestly
Every number here is vendor-published on a specific micro-scenario. I have not reproduced any of them. Attribute the source and name the scenario before you repeat a ratio.
- Production build. VoidZero reports Vite+ builds are roughly 1.6x to 7.7x faster than Vite 7, and cites Linear’s build dropping from 46 seconds to 6 seconds. The range is wide because the speedup depends on the project.
- Lint and format. Oxlint is cited at up to about 100x faster than ESLint, with 600+ ESLint-compatible rules, and Oxfmt at up to about 30x faster than Prettier, with roughly 99% Prettier compatibility.
- Script dispatch. Nub reports its
rundispatch (a warm no-op echo) at about 24x versuspnpm run, but only about 2.2x versus Node’s ownnode --run. Nub is explicit that the absolute numbers are machine-specific and only the ratios travel. - Bin runner.
nubxis cited at about 19x to 20x versusnpx. - Install. Nub’s README claims 18x faster
pnpm install, while secondary write-ups report closer to 2.5x. Same tool, different cache state (warm no-op versus cold). Name the scenario or drop the number.
The install figure is the clearest warning. A headline “24x faster than pnpm run” quietly becomes about 2.2x once you compare against node --run on Node 22 and later. The ratio you quote is only as honest as the baseline you picked, so pick the baseline your team actually runs today.
One binary for everything
Collapsing seven tools into one binary re-introduces the coupling the JavaScript ecosystem spent a decade escaping. Whether that is progress or a new monolith comes down to one question: how expensive is it to leave?
Vite+ leans fully into integration. It owns the dev server, the bundler, the test runner, the linter, the formatter, the task runner, and the package-manager and runtime slots. Its strategic backing also changed: VoidZero announced it is joining Cloudflare on June 4, 2026. At the same time it grew more open, not less. The original October 2025 plan was commercial and source-available, free only for individuals, open source, and small businesses; that reversed at the March 2026 alpha, and the beta remains fully MIT. So the license risk fell while the surface area it owns grew.
Nub makes the opposite bet. It augments stock Node instead of replacing it, ships no vendor-specific API, and keeps working with your existing lockfiles. You can remove it and land back on node, tsx, and pnpm with no migration.
That is the honest way to read the monolith question. Consolidation is progress where the binary absorbs configuration you never wanted to own, such as the six lint, format, and bundler configs that only ever fought each other. It becomes a monolith risk where it absorbs decisions you want to keep reversible, such as which runtime runs your production service or who owns your package graph. Judge each binary by its exit cost, not by its install-speed chart.
When to reach for something else
Three cases fall outside the default.
- A pure static site with a trivial toolchain. Neither binary earns its place; a plain bundler or a framework’s built-in tooling is enough.
- You already run Bun or Deno in production. Nub’s whole premise is stock-Node parity, so it solves a problem you do not have; your runtime already collapsed the toolchain.
- You need a mature monorepo task graph today.
vp runis newer and simpler than Turborepo or Nx. If you depend on a proven task graph with remote caching at scale, keep the tool you trust and let Vite+ own only the parts it clearly leads.
Under all three sits the pre-1.0 question. Vite+ is in beta and Nub is pre-1.0 (v0.4.x). If pre-1.0 risk is unacceptable for the repo in question, the fallback is boring and fine: plain Vite 8 with assembled tools on the frontend, and tsx plus pnpm plus fnm on the backend.
Common pitfalls
- Treating them as head-to-head competitors and letting an install-speed number pick the winner. They sit on different layers.
- Adopting Nub and expecting a browser dev server or a production browser bundle. It has neither.
- Adopting Vite+ to run a backend service you never bundle for a browser. That is not what
vpis for. - Repeating a vendor benchmark as a measured fact. Each number is tied to one micro-scenario, so attribute it.
- Quoting Nub’s 24x
runfigure without noticing it is about 2.2x againstnode --run. The headline depends entirely on your current baseline.
Conclusion
The rule holds for the common cases. If the build output loads in a browser, or you need one tool to own a full-stack monorepo’s package-manager and runtime slot, standardize on Vite+. If the build output is a Node process (a backend service, a CLI, a library, or a pile of scripts) and it must stay on stock Node, reach for Nub to run, watch, and install. They are not substitutes, so let the artifact decide, and do not draft either one to do the other’s job. Reach for an override when the toolchain is trivial, when you already run Bun or Deno, or when pre-1.0 risk is off the table for that repo.
This comparison maps the tools; it does not benchmark them. The next step is a small, conceptual POC: run one TypeScript service under nub and one web app under vp, and record where each abstraction leaks. Until that runs, treat every ratio above as a vendor claim tied to a specific scenario, not a measured result.
References
- Announcing Vite+ Beta - The July 2, 2026 beta post; the authoritative
vpcommand surface, bundled tools, and adoption stats. - Announcing Vite+ - The October 13, 2025 original announcement, home of the Oxlint and build benchmark figures and the commercial, source-available licensing plan later reversed.
- voidzero-dev/vite-plus - The Vite+ source repository, with components, issues, and releases.
- Vite+ documentation - The official guide, including the
vp migratepath and its manual-follow-up caveat. - VoidZero is Joining Cloudflare - The June 4, 2026 ownership change that reframes Vite+‘s strategic backing and lock-in profile.
- Announcing VoidZero Inc. - The founding post and the open-source commitment used to judge the later licensing reversal.
- Nub: all-in-one toolkit for Node.js - The official homepage; positioning and a command overview.
- Introducing Nub - The launch post with per-command benchmarks and the explicit “ratios, not absolute numbers” caveat.
- nubjs/nub - The source and README, including the replacement table, the 18x install claim, and version and author provenance.
- Rewriting Bun in Rust - Bun’s own account of its 2026 Zig-to-Rust rewrite under Anthropic, confirming it stays on JavaScriptCore rather than oxc.
- Vite+: 7.7x Faster Builds, Why You Should Wait - A skeptical practitioner take that acts as a counterweight to the vendor framing.
- I Tried Vite+ and Replaced My Entire Frontend Toolchain - A practitioner’s hands-on take, focused on
vp createscaffolding rather than a full migration.
Related posts
How native tools like esbuild, SWC, and Vite solved webpack's speed problems, taking builds from tens of seconds down to milliseconds.
How Google's 2009 Closure Compiler shaped modern web tooling, from dead code elimination to type checking, and its lasting mark on today's build tools.
Bake a single PII branded type into your observability API signatures so TypeScript rejects sensitive fields at the call site, before any runtime redactor sees them.
A practical introduction to idempotency for developers building APIs, payments, and message consumers, covering HTTP semantics, idempotency keys, and upserts.
A practical comparison of TypeScript AI SDKs for building agents: Vercel AI SDK, OpenAI Agents SDK, and AWS Bedrock, with code examples and decision frameworks.