# Nub: An All-in-One JavaScript Toolkit That Augments Node.js


**The Node.js development experience typically involves a small collection of separate tools**: `tsx` or `ts-node` for running TypeScript, `nvm` for Node version management, `dotenv` for environment variable loading, `npx` for package binaries, and `npm run` or `pnpm run` for scripts. Each works fine independently, but together they add configuration overhead and startup latency.

[Nub](https://nubjs.com), launched on June 15, 2026 by Colin McDonnell (creator of Zod, former Bun employee), **replaces all of them with a single Rust binary**. Its distinguishing design choice is to augment Node.js rather than replace it. You keep the stock Node runtime your project already pins; **Nub adds TypeScript support, faster script dispatch, package management, Node version management, and `.env` loading on top of it**. On Deno's own Node compatibility corpus, Nub passes 98.8% of what real Node passes, versus 77.4% for Deno and 40.5% for Bun.

The project is at v0.4.x, MIT-licensed, and available at [github.com/nubjs/nub](https://github.com/nubjs/nub).

<iframe class="aspect-video h-auto" width="100%" height="315" src="https://www.youtube.com/embed/6YRpXxbtc2c" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>


## Installation

Nub runs on macOS, Windows, and Linux.

Install via the shell script:

```command
curl -fsSL https://nubjs.com/install.sh | bash
```

Or via npm:

```command
npm install -g @nubjs/nub
```

Or via Homebrew on macOS:

```command
brew install nubjs/tap/nub
```

![A screenshot of the Nub.js homepage showing the primary installation command.](https://imagedelivery.net/xZXo0QFi-1_4Zimer-T0XQ/2b2f7ece-60da-488c-fe08-72a6e800ad00/md2x =1280x720)

Verify the installation:

```command
nub --version
```

## Running TypeScript files

Node.js added TypeScript type-stripping in recent versions, but it only handles types that can be erased. Code that uses `enum`, `namespace`, or constructor parameter properties fails with `ERR_UNSUPPORTED_TYPESCRIPT_SYNTAX` because these features have no direct JavaScript equivalent.

Nub uses [oxc](https://oxc.rs) for transpilation and handles all TypeScript syntax correctly:

```typescript
[label strip-limits.ts]
enum Status {
  Draft,
  Published,
  Archived,
}

namespace Meta {
  export const engine = "oxc";
}

class Money {
  constructor(
    public currency: string,
    private amount: number,
  ) {}
}

console.log('enum:', Status.Published);
console.log('namespace:', Meta.engine);
const myMoney = new Money('GBP', 38.24);
console.log('param properties:', myMoney);
```

```command
nub demos/type-stripping/strip-limits.ts
```

![The terminal output after running the TypeScript file with Nub, showing the successful execution and printed logs, contrasted with a note indicating where standard Node.js would fail.](https://imagedelivery.net/xZXo0QFi-1_4Zimer-T0XQ/8d7d45af-9003-4c0c-822b-b2b1c58a0400/lg2x =1280x720)

## Automatic `.env` loading

Nub detects and loads environment variable files without any configuration or `dotenv` dependency. It checks for files in this order of precedence:

1. `.env`
2. `.env.local`
3. `.env.[NODE_ENV]`
4. `.env.[NODE_ENV].local`

Variable expansion is handled automatically. You can compose variables from other variables in the same file:

```dotenv
[label .env]
DB_HOST=localhost
DB_PORT=5432
DB_USER=admin

DATABASE_URL=postgres://${DB_USER}@${DB_HOST}:${DB_PORT}/kitchen_sink
```

`DATABASE_URL` is resolved and available in `process.env` when you run any file with Nub.

![An example `.env` file within a code editor, highlighting the line with `DATABASE_URL` to showcase the variable expansion syntax.](https://imagedelivery.net/xZXo0QFi-1_4Zimer-T0XQ/7515ef8b-8cf5-42ad-5b65-f9c52e62eb00/md1x =1280x720)

## Data file imports and path aliases

### Data file imports

Nub lets you import JSON, YAML, TOML, and plain text files directly as modules:

```typescript
import config from './config.json';
import settings from './settings.yaml';
import serverConfig from './server.toml';
import motd from './motd.txt';
```

### Path aliases

If your `tsconfig.json` defines path aliases, Nub resolves them automatically at runtime without needing `tsconfig-paths` or any additional setup:

```json
[label tsconfig.json]
{
  "compilerOptions": {
    "paths": {
      "@config/*": ["./config/*"],
      "@/lib/*": ["./src/lib/*"]
    }
  }
}
```

![A screenshot of a `tsconfig.json` file, with the "paths" object highlighted to show how aliases are configured.](https://imagedelivery.net/xZXo0QFi-1_4Zimer-T0XQ/2324e59b-e1af-464c-6969-3690214d0a00/md1x =1280x720)

```typescript
import serverConfig from '@config/server.toml';
import { render } from '@/lib/ui';
```

## Modern APIs and polyfills

Nub polyfills modern web APIs on older Node versions and auto-enables experimental Node features so you don't need to pass command-line flags manually.

![A grid view from the Nub website listing the various modern APIs and syntax that a![frame_2_43.jpg](https://imagedelivery.net/xZXo0QFi-1_4Zimer-T0XQ/7c448ceb-1731-46bd-2d5e-b226ee372700/md2x =1280x720)

Included polyfills:

- **Web Workers**: browser-shaped `Worker` constructor over `node:worker_threads`
- **Temporal API**: native in Node 26+; polyfilled with `@js-temporal/polyfill` on older versions
- **URLPattern**: native in Node 24+; polyfilled on older lines
- **`using` / `await using`**: explicit resource management
- **Decorators**: class and method meta-programming

## Node version management

Nub includes an automatic Node version manager. When you run any `nub` command in a project, it checks for a version specification in this order:

1. `.node-version` file
2. `.nvmrc` file
3. `engines` field in `package.json`

If the specified version isn't installed, Nub downloads it on demand:

```text
[output]
Installing from nodejs.org... (28 MB)
Installed in 2.4s
Using Node.js 24.18.0
```

For manual version management:

```command
nub node install 23
```

```command
nub node ls
```

```command
nub node uninstall 23.11.1
```

```command
nub node pin 26
```

`nub node pin` creates a `.node-version` file in the project directory, which Nub (and other compatible tools) will pick up automatically.

## Package management

Nub's package manager is built on the [Aube](https://github.com/jdx/aube) engine. The key design decision is lockfile compatibility: rather than introducing a new lockfile format, Nub reads and updates whichever lockfile your project already uses.

- `package-lock.json` (npm)
- `pnpm-lock.yaml` (pnpm)
- `bun.lock` (Bun)

```command
nub install
```

### `nubx` instead of `npx`

`nubx` replaces `npx` for running package binaries. Where `npx` is a Node.js script that boots a process and resolves the binary through JavaScript, `nubx` is a native Rust binary that resolves the path in `node_modules/.bin` directly and executes immediately.

```command
nubx prettier --write .
```

### `nub run` for scripts

`nub run` replaces `npm run` and `pnpm run` for executing `package.json` scripts. It reads `package.json` natively in Rust and spawns the process directly, avoiding the JavaScript startup penalty. Lifecycle hooks, argument forwarding, and `npm_*` environment variables all work as expected.

```command
nub run dev
```

The performance numbers Nub publishes are vendor benchmarks on specific scenarios, not independent measurements, so treat them as directional rather than absolute. The architectural reason for the improvement is real: eliminating a Node.js process just to dispatch another Node.js process removes meaningful overhead, especially in CI and monorepos where scripts run frequently.

## Design philosophy

Nub introduces no Nub-specific APIs. There is no `nub` global, no `nub:` prefixed built-in modules, no Nub-named config file, no Nub lockfile, and no `NUB_` environment variables. It uses Node's own public extension surfaces: `module.registerHooks()`, `--import` preloads, and N-API native addons. If you stop using Nub, your code still runs with stock Node.

One caveat worth noting: **Nub transpiles TypeScript but does not type-check it. You still need `tsc --noEmit` in CI for type safety. Nub is a development and script execution toolkit, not a production runtime**.

The official introduction post at [nubjs.com/blog/introducing-nub](https://nubjs.com/blog/introducing-nub) covers each feature in more depth, including the polyfill implementation details and the compatibility methodology.

