Run whatever a name points to with one command — a file, a package.json script, a local bin, or a package off the registry.

nubx index.ts          # run a file
nubx test --snapshot   # run a package.json script
nubx rolldown -b       # run a local CLI
nubx cowsay "hi"       # run a remote CLI (dlx)

Reach for nubx first. It resolves the name through every tier and runs the first match, so one command covers the file you wrote, the script in your package.json, the CLI already in node_modules, and the tool you haven't installed yet. The single-purpose commands it unifies — nub run, nub exec, and nub dlx — stay available when you want exactly one tier.

Resolution order

A bare token resolves by the first tier that matches:

  • File — a path (./x, /abs/x) or a file by that name in the current directory
  • Script — a package.json script of that name
  • Local bin — an executable on the node_modules/.bin chain
  • Registry — a package fetched and run, when nothing local matched

Scripts beat bins, and a file beats both — the same precedence as nub run. A leading -p/--package spec skips local resolution and fetches.

Each tier mirrors a standalone command — nubx picks the right one for you:

nubx <file>        # equivalent to `nub <file>`
nubx <script>      # equivalent to `nub run <script>`
nubx <local-bin>   # equivalent to `nub exec <local-bin>`
nubx <remote-bin>  # equivalent to `nub dlx <remote-bin>`

Other runners cover only a slice — node runs files, npx runs or fetches a bin, and pnpm splits the job across run, exec, and dlx:

Targetnodepnpmpnpm runpnpm execpnpm dlxnpxpnpxnubx
JS/TS file
package.json script
Local bin
Registry package

Only npx and nubx fall through from local to the registry in one command — npx for a bin, nubx for the full chain. Every pnpm command targets one tier and errors on a miss.

Coming from npx

Two deliberate differences. A local script or file wins, not just a bin — if a project has both a lint script and a lint bin, nubx lint runs the script (use nub exec lint to force the bin). And a registry fetch needs consent: where npx downloads silently, nubx prompts on the first fetch and fails closed in CI, so add -y or declare the tool as a dependency.

Fetch from the registry

When nothing local matches, nubx can fetch a package, run its bin, and remember your consent — but it never runs remote code silently. The first run of a given tool prompts:

$ nubx cowsay "Hello"
nubx: cowsay is not installed locally. Download and run it? [y/N] y
dependencies:
+ cowsay@1.6.0

 _______
< Hello >
 -------
        \   ^__^
         \  (oo)\_______
            (__)\       )\/\
                ||----w |
                ||     ||

Answer y once and later runs skip the prompt. A pinned version (nubx cowsay@1.5.0) is remembered indefinitely; a floating one (nubx cowsay, which tracks latest) is re-confirmed after a day, so a tool that has moved to a new version asks again before running new code.

Outside a terminal there's no way to ask, so nubx fails closed — in CI, and any time stdin isn't a terminal:

$ nubx cowsay "hi"          # in CI
nubx: refusing to download cowsay in CI.
  A CI job should declare the tool as a dependency, or pass -y to fetch it.

A fetched package runs through Nub's normal install resolver, so the registry safeguards apply: the minimumReleaseAge cooling window (see the trust floor) and skipped lifecycle scripts. The remote bin runner is the explicit way to fetch and run a package outside the prompt, and covers both in full.

-y

Pass -y (--yes) to consent up front: it lets a fetch through in CI or any non-interactive context and skips the first-run prompt. This is the deliberate "yes, download and run it" gesture for scripts and CI.

nubx -y cowsay "hi"

Pass arguments

Everything after the name goes to the underlying file, script, or tool untouched — there's no -- separator to remember.

nubx eslint . --fix --max-warnings 0
nubx vitest run --coverage

--node

Pass --node to run the tool with runtime augmentation disabled — see the runtime overview for the full contract. Resolution, the registry fetch, and nubx's own machinery still run; only the augmentation is off.

nubx --node prisma generate