Swap actions/setup-node for nubjs/setup-nub and the rest of your workflow keeps working:

steps:
  - uses: actions/checkout@v4
  - uses: nubjs/setup-nub@v1
  - run: nub install
  - run: nub test

The action installs the nub CLI onto the runner. From there Nub resolves and provisions the project's pinned Node itself, so you no longer pick a Node version in the workflow — the pin in .node-version / .nvmrc / engines.node is the single source of truth.

How it differs from setup-node

The actions/setup-node action installs a Node version you name in the workflow, and that version is what your steps run. The setup-nub action installs the nub CLI; Nub then runs the project's declared pin at runtime. A Node version in the workflow is only a warm-up hint — Nub still runs the project pin regardless.

That makes the inputs you'd reach for different:

# setup-node — the workflow picks the Node version
- uses: actions/setup-node@v4
  with:
    node-version: 22

# setup-nub — the project pin picks the Node version
- uses: nubjs/setup-nub@v1
# nub reads .node-version / .nvmrc / engines.node on first run

The setup-node inputs (node-version, cache, registry-url, …) are all accepted, so a mechanical swap is safe. The ones Nub can't honor are accepted and ignored rather than erroring.

node-version

Pass a version to pre-provision it into Nub's cache during setup, so the first run is warm. This is a warm-up hint, not a pin — if it differs from the project's declared pin, the action emits a warning and Nub runs the project pin.

- uses: nubjs/setup-nub@v1
  with:
    node-version: 22.15.0

Read the version from a file instead with node-version-file:

- uses: nubjs/setup-nub@v1
  with:
    node-version-file: .node-version

Both are redundant with Nub's own resolution — Nub provisions the pin lazily on first use without either input. Reach for them only when you want the download to happen in the setup step.

cache

Cache Nub's global store and provisioned Node toolchains across runs. Off by default; turn it on with a boolean:

- uses: nubjs/setup-nub@v1
  with:
    cache: true

The cache key is derived from the project's lockfile, auto-detected in this order:

pnpm-lock.yaml
package-lock.json
bun.lock
bun.lockb
yarn.lock

Override the auto-detection with cache-dependency-path — a lockfile path, glob, or newline-delimited list:

- uses: nubjs/setup-nub@v1
  with:
    cache: true
    cache-dependency-path: |
      app/pnpm-lock.yaml
      packages/*/pnpm-lock.yaml

A cache-hit output reports whether the store was restored. A restore-keys ladder gives a partial warm hit even when the lockfile changes.

registry-url

Set up authenticated registry access. The action writes a project-level .npmrc — the neutral file Nub's package manager reads — and binds the auth token to the NODE_AUTH_TOKEN environment variable:

- uses: nubjs/setup-nub@v1
  with:
    registry-url: https://registry.npmjs.org
- run: nub install
  env:
    NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}

For GitHub Packages, point at the registry and the scope defaults to the repository owner:

- uses: nubjs/setup-nub@v1
  with:
    registry-url: https://npm.pkg.github.com
- run: nub install
  env:
    NODE_AUTH_TOKEN: ${{ secrets.GITHUB_TOKEN }}

Set scope explicitly for a scoped registry, and always-auth: true to authenticate on every request. The .npmrc follows the same contract as setup-node, so existing auth setups port over unchanged.

nub-version

Pin the CLI version to install — any semver range npm understands. Defaults to the latest release:

- uses: nubjs/setup-nub@v1
  with:
    nub-version: ^0.0

Inputs

InputDefaultDescription
nub-versionlatestVersion of nub to install — any semver range npm understands.
node-versionPre-provision this Node version into the cache as a warm-up hint.
node-version-fileRead a Node version from a file and pre-provision it.
cachefalseCache Nub's store and provisioned Node toolchains across runs.
cache-dependency-pathLockfile path(s) whose hash keys the cache.
registry-urlRegistry to set up for auth; writes a project-level .npmrc.
scopeScope for a scoped registry; falls back to the repository owner for GitHub Packages.
always-authfalseAuthenticate on every registry request.
tokengithub.tokenToken for GitHub-API rate-limit relief when resolving versions.

The setup-node inputs check-latest, architecture, mirror, and mirror-token are accepted and ignored — present so a swap never errors, with no effect in v1. A version input survives as a deprecated alias for nub-version and emits a warning.

Outputs

OutputDescription
nub-versionThe installed nub version.
node-versionThe Node version Nub resolves for the project; empty when nothing was provisioned.
cache-hitWhether the store cache was restored; only meaningful with caching on.
  • Node manager — how Nub provisions and pins Node versions.
  • Package manager — the install surface the action's registry auth feeds.