p.enthalabs

GitHub - nubjs/nub: The fast all-in-one Node.js toolkit

![Image 1: Nub logo](https://camo.githubusercontent.com/ccc0686b675dfa20501426cc5efa05a3f5c3033031b2ba6b294535eba0bf3b49/68747470733a2f2f6e75626a732e636f6d2f69636f6e2d626f726465722e737667)

A fast all-in-one toolkit that augments Node.js instead of replacing it

![Image 2: stars](https://github.com/nubjs/nub)

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

[](https://github.com/nubjs/nub#install)

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

mise

mise use -g nub

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>`

[](https://github.com/nubjs/nub#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`/`--require` preloads > * `module.registerHooks()` for transpilation and resolution > * N-API native addons: Nub embeds oxc for pre-transpilation

Node provisioning

[](https://github.com/nubjs/nub#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`

- `.nvmrc`

- `package.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

[](https://github.com/nubjs/nub#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

[](https://github.com/nubjs/nub#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*`, the `tsconfig.json` extends chain, `package.json`

- โš™๏ธ Runs on Node's own `--watch` engine, preserving output by default

View the full runtime docs ๐Ÿ‘‰.

Script runner โ€” `nub run`

[](https://github.com/nubjs/nub#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`/`post` hooks and the complete `npm_*` environment

- ๐Ÿงฐ Local `node_modules/.bin` on `PATH`, with args forwarded without the `--` separator

- ๐Ÿ—ƒ๏ธ The full pnpm workspace surface โ€” `-r`, `--filter`, `--parallel`, `--workspace-concurrency`, `--resume-from`, `--stream`

- ๐ŸŽฏ pnpm's `--filter` grammar verbatim โ€” graph (`...@org/web`) and changed-since (`[main]`) selectors

View the full script runner docs ๐Ÿ‘‰.

Package runner โ€” `nubx` / `nub dlx`

[](https://github.com/nubjs/nub#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 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/.bin` regardless of which package manager installed it

- ๐ŸŒ Registry fallback for uninstalled bins โ€” fetched, run, then discarded

- ๐Ÿงฉ Full `pnpm exec` / `pnpm dlx` flag 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`

[](https://github.com/nubjs/nub#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

[](https://github.com/nubjs/nub#security)

- ๐Ÿ›ก๏ธ Blocks postinstall by default

- ๐Ÿฆ  Checks osv.dev for known-malicious package versions during resolution by default

- ๐Ÿ”ป Refuses provenance downgrades by default

- โณ 24-hour `minimumReleaseAge` by default

Compatibility

[](https://github.com/nubjs/nub#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`

[](https://github.com/nubjs/nub#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`

[](https://github.com/nubjs/nub#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

[](https://github.com/nubjs/nub#license) MIT

> _โญ๏ธ If you read this far, consider starring the repo :) โญ๏ธ_