Show HN: Nub – A Bun-like all-in-one toolkit for Node.js
Summary
Nub is a fast all-in-one toolkit for Node.js that provides a Bun-like developer experience, including running TypeScript files, managing dependencies, and Node versions, all in one CLI tool written in Rust.
View Cached Full Text
Cached at: 06/24/26, 04:52 PM
nubjs/nub
Source: https://github.com/nubjs/nub
Nub
A fast all-in-one toolkit that augments Node.js instead of replacing it
A Bun-like DX on top of stock node, written in Rust.
nub index.ts # TypeScript-first Node.js runtime
nub run dev # 24× faster pnpm run
nubx prisma generate # 19× faster npx
nub install # 2.5× faster pnpm install
nub watch src/server.ts # native watch mode
nub pm shim # built-in Corepack-style shims
nub node install 26 # Node version manager
nub upgrade # self update
One tool to run your files and scripts, install dependencies, and manage Node itself. No new runtime, no vendor-specific API surface, no lock-in.
| Nub | Instead of |
|---|---|
nub <file> | node, tsx, ts-node, dotenv-cli |
nub run <script> | npm run, pnpm run |
nubx | npx, pnpm dlx / exec |
nub install | npm, pnpm |
nub watch | nodemon, node --watch, tsx watch |
nub node | nvm, fnm, n, volta |
nub pm | corepack |
Install
# macOS / Linux
curl -fsSL https://nubjs.com/install.sh | bash
# Windows (PowerShell)
irm https://nubjs.com/install.ps1 | iex
# Or via npm (pnpm / yarn global add work too)
npm install -g --ignore-scripts=false @nubjs/nub
For GitHub Actions, use nubjs/setup-nub in place of actions/setup-node. It’s one-to-one compatible.
- - uses: actions/setup-node@v4
+ - uses: nubjs/setup-nub@v0
File runner — nub <file>
Run a file. Supports .js, .ts, .mjs, .cjs, .mts, .cts, .jsx, and .tsx. Flag-for-flag and var-for-var drop-in compatible with node (mostly via passthrough).
nub index.ts # TypeScript, JSX, no build step
nub --watch app.ts # same path, restart-on-change
It augments stock Node with some of Bun/Deno’s best features:
- 🦆 Full TypeScript support, including
enum,namespace - 🧭 TypeScript-friendly resolution: extensionless imports,
tsconfig.json#paths - ⚛️ JSX / TSX
- 🎂 Decorators and
emitDecoratorMetadata - 🆕 Modern syntax like
using(downleveled in transpiler when needed) - 🔐 Automatic
.env*loading — Next.js/Vite parity - 🗂️ Built-in loaders for common data formats —
.yaml,.toml,.jsonc,.json5,.txt - 🌐 Polyfills for
Temporal,Worker,URLPattern(when needed) - 🔥 Unflags experimental features like
node:sqlite,vm.Module,localStorage,WebSocket,EventSource - ⚡ 2.9× faster startup than
tsx
How it works — Nub takes advantage of Node extension surfaces that mostly didn’t exist when Deno and Bun were built:
--import/--requirepreloadsmodule.registerHooks()for transpilation and resolution- N-API native addons: Nub embeds oxc for pre-transpilation
Node provisioning
When you run a file with nub, it infers the version of Node your project expects and auto-installs it if needed. It respects (in precedence order):
NODE_EXECUTABLE(override)package.json#devEngines.node-version.nvmrcpackage.json#engines
This resolved version of Node is installed and your file is executed with it (with Nub’s augmentations).
$ echo 26 > .node-version
$ nub hello.ts
Using Node.js 26.3.0 (resolved from .node-version)
Installed in 9.8s
Hello world!
Modern APIs
Modern API work out of the box under Nub. Node.js experimental APIs are unflagged, others are auto-polyfilled (e.g. Temporal on Node 25 and earlier), and others are downleveled in the transpiler (using).
| API | How |
|---|---|
Temporal | polyfilled below Node 26, native above |
URLPattern | polyfilled below Node 24, native above |
RegExp.escape | polyfilled below Node 24, native above |
Error.isError | polyfilled below Node 24, native above |
Promise.try | polyfilled below Node 24, native above |
Float16Array | polyfilled below Node 24, native above |
navigator.locks | polyfilled below Node 24.5, native above |
reportError | polyfilled |
vm.Module | unflagged |
ShadowRealm | unflagged |
Wasm module imports | unflagged below Node 24.5 (22.19 on the 22.x line), native above |
WebSocket | unflagged from Node 20.10, native from Node 22 |
EventSource | unflagged from Node 20.18, native above |
node:sqlite | unflagged from Node 22.5, native from Node 22.13 |
addon imports | unflagged from Node 22.20, never native |
Watch mode
Restart-on-change driven by the resolved dependency graph plus the off-graph files that still invalidate a run — no glob list to maintain:
nub watch src/server.ts
nub --watch src/server.ts # same path
- 👀 Tracks the resolved dependency graph automatically
- 🧷 Also watches the off-graph invalidators —
.env*, thetsconfig.jsonextends chain,package.json - ⚙️ Runs on Node’s own
--watchengine, preserving output by default
View the full runtime docs 👉.
Script runner — nub run
A drop-in for npm run and pnpm run. The runner is a Rust binary with no JavaScript startup of its own, so it dispatches a warm script roughly 24× faster than pnpm run:
nub run build
nub run -r --filter "@org/*" test # supports --filter
It’s fast compared to existing JavaScript-based script runners.
| Command | Time | Relative |
|---|---|---|
nub run | 14.7 ms | — |
npm run | 329.9 ms | 22× |
pnpm run | 442.7 ms | 30× |
script dispatch · warm · 50 runs · macOS — view benchmark
- 🚀 Feels instantaneous — 14ms vs a detectable 300ms+ lag for npm/pnpm
- 🔁 Full lifecycle support —
pre/posthooks and the completenpm_*environment - 🧰 Local
node_modules/.binonPATH, with args forwarded without the--separator - 🗃️ The full pnpm workspace surface —
-r,--filter,--parallel,--workspace-concurrency,--resume-from,--stream - 🎯 pnpm’s
--filtergrammar verbatim — graph (...@org/web) and changed-since ([main]) selectors
View the full script runner docs 👉.
Package runner — nubx / nub dlx
A drop-in for npx and pnpm dlx. Local-first with a download-and-execute registry fallback (same as npx). Eliminating the double-Node.js-spawn performance penalty paid by JavaScript-based tools like npx and pnpm.
nubx eslint . --fix
nubx -y [email protected] "hi" # fetched from the registry (auto-approved via -y)
| Command | Time | Relative |
|---|---|---|
nubx esbuild --version | 11 ms | — |
pnpm exec esbuild --version | 191 ms | 17× |
npx esbuild --version | 226 ms | 19× |
esbuild –version · macOS — view benchmark
- ⚡ Runs a local bin ~19× faster than
npx, with no Node in the wrapper - 🔎 Resolves
node_modules/.binregardless of which package manager installed it - 🌐 Registry fallback for uninstalled bins — fetched, run, then discarded
- 🧩 Full
pnpm exec/pnpm dlxflag parity, shell mode included - 🪜 Walks the resolution chain — member
.bin, then workspace root, then ancestors
View the full package runner docs 👉.
Package manager — nub install
Nub is a package manager powered by the Aube engine. The CLI is flag-for-flag compatible with pnpm for muscle memory, but
nub install
nub ci
nub add -E -D --save-catalog react
nub remove lodash
nub update
nub dedupe
It’s fast — avoids the per-command Node.js bootstrap lag incurred by JS-based package managers.
| Tool | Time | Relative |
|---|---|---|
nub | 1122 ms | — |
bun | 1444 ms | 29% slower |
pnpm | 2847 ms | 2.5× |
npm | 4163 ms | 3.7× |
warm frozen install · create-t3-app · 222 deps · macOS — view benchmark
Security
- 🛡️ Blocks postinstall by default
- 🦠 Checks osv.dev for known-malicious package versions during resolution by default
- 🔻 Refuses provenance downgrades by default
- ⏳ 24-hour
minimumReleaseAgeby default
Compatibility
When you run nub install inside a project, it detects the incumbent package manager (based on your package.json#packageManager or any detected lockfiles). It then runs in compat-mode, respecting the config files and environment variables for that package manager.
Under each incumbent, Nub reads that tool’s branded config and no other’s; the neutral .npmrc cascade and npm_config_* are read under every one.
| Incumbent | Config it reads |
|---|---|
| npm | package-lock.json, .npmrc, overrides, workspaces, engines/os/cpu/libc |
| pnpm | pnpm-lock.yaml, pnpm-workspace.yaml, .pnpmfile.cjs, package.json#pnpm, resolutions, catalog:, .npmrc |
| Yarn (read-only) | yarn.lock, a .yarnrc.yml / .yarnrc subset, YARN_*, resolutions, packageExtensions, .npmrc |
| Bun | bun.lock, bunfig.toml [install], trustedDependencies, overrides, patchedDependencies, catalog:, .npmrc |
| Nub | neutral only — .npmrc, npm_config_*, overrides / resolutions / catalog / workspaces |
View the full package manager docs 👉.
Package meta-manager — nub pm
Corepack’s job, in native Rust: provision and run the exact pnpm / npm / yarn your project pins:
nub pm shim # registers global shims (Corepack-style)
Like corepack enable, this registers global shims for npm, yarn, and pnpm. When you run a command using one of these shim aliases anywhere on your file system, the shim will:
- Detect the version used in your project
- Install that version if needed
- Run the command using the proper version
Nub provides this functionality as a convenience for users who prefer to keep their current package manager. Corepack itself was unbundled from Node itself in v25.
View the full nub pm docs 👉.
Node version manager — nub node
Though Node.js versions will generally be auto-installed and cached as needed, you can manage versions manually as well.
$ nub node -h
nub node — manage Node versions
Usage: nub node <command>
Commands:
which print the resolved Node binary path (why → stderr)
install [<version>...] provision version(s) into nub's cache
ls list versions in nub's cache
uninstall <version> remove a version from nub's cache
pin <version> write the project's Node pin
View the full nub node docs 👉.
License
MIT
Similar Articles
@colinhacks: Introducing Nub. The all-in-one JavaScript toolkit that augments Node.js (instead of trying to replace it)
Introducing Nub, an all-in-one JavaScript toolkit that augments Node.js instead of replacing it.
oven-sh/bun
Bun is an all-in-one toolkit for JavaScript and TypeScript apps, providing a fast runtime, package manager, and test runner as a single executable. It aims to be a drop-in replacement for Node.js with significantly faster startup and lower memory usage.
Show HN: Mochi.js: bun-native high-fidelity browser automation library
Mochi.js is a new open-source browser automation library built natively for the Bun runtime, designed to bypass detection mechanisms with relational consistency, native Chromium fetching, and behavioral synthesis.
Show HN: Nibble
Nibble is a C-like systems programming language implemented in 3000 lines of C that generates LLVM IR without external dependencies or heap allocations. It supports defer, recursion, various types, structs, pointers, and includes graphical demos.
aube, a fast Node.js package manager
Aube is introduced as a new, high-performance Node.js package manager that is significantly faster than pnpm and bun while using less disk space by utilizing a global store for dependencies.