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 updateOne 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 |
# macOS / Linux
curl -fsSL https://nubjs.com/install.sh | bash
# Windows (PowerShell)
irm https://nubjs.com/install.ps1 | iex
# Homebrew (macOS / Linux)
brew install nubjs/tap/nub
# Nix (flakes)
nix run github:nubjs/nub
# Or via npm (pnpm / yarn global add work too)
npm install -g --ignore-scripts=false @nubjs/nubFor 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@v0Run 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-changeIt 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
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 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 |
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 π.
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 --filterIt'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 π.
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 cowsay@1.5.0 "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 π.
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 dedupeIt'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
- π‘οΈ 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
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 π.
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 π.
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 pinView the full nub node docs π.
MIT
βοΈ If you read this far, consider starring the repo :) βοΈ