~/docs/essentials/node-management
╭─ § 02.04 ─╮

Node.js Management

└───────────╯

Corral manages Node.js installations for you — download versions on demand, pin them per project, and run commands with the right version automatically. No need for nvm, fnm, or any other version manager.

Version Resolution

When starting a project or running a command, Corral resolves the Node.js version in this order:

PrioritySourceExample
1--node-version flagcorral exec --node-version 22 node -v
2CORRAL_NODE_VERSION env varexport CORRAL_NODE_VERSION=22
3Per-project Corral settingcorral project set my-worker node-version 22
4.node-version file in the project directory22.3.0
5.nvmrc file in the project directory22
6App-wide default versioncorral settings set default-node-version 22
7Latest installed versionWhatever’s newest in ~/.corral/runtimes/node/

The first match wins. A .node-version file in your project overrides the app-wide default, and the flag overrides everything.

When a pinned version isn’t installed

A pin only matches versions you actually have. If your project asks for Node 22 and only Node 20 is installed, Corral falls through to the next source in the table and ends up on the newest version it manages — so the project runs on 20.

It will tell you when that happens:

  ⚠  Node 22 isn't installed (.nvmrc).
     Using Node 20.11.0 instead.
     Fix: corral node install 22

The same applies to a version Corral can’t read at all — a typo in .nvmrc, say. It’s reported and skipped, never treated as an instruction to stop.

The one thing that is a hard error

--node-version 22 fails outright if 22 isn’t installed. You named that version in that command, so quietly running a different one would be worse than stopping.

Row 2 is deliberately not in that category. CORRAL_NODE_VERSION is ambient configuration — you export it once and it applies to every command in the shell from then on, which makes it a pin like .nvmrc, not a per-command instruction. Treating it as explicit would mean one line in a shell profile could stop node, npm, and npx from running at all.

Installing Node.js Versions

Install a specific version:

corral node install 22.3.0

Install the latest in a major version:

corral node install 22

Install the latest LTS:

corral node install lts

Corral downloads official binaries from nodejs.org and verifies their SHA256 checksums. Installations are stored in ~/.corral/runtimes/node/v{version}/.

List installed versions:

corral node list

See what’s available:

# All versions (20 most recent)
corral node available

# LTS versions only
corral node available --lts

Remove a version:

corral node remove 22.3.0

Version Specification

You can specify versions in several formats:

FormatExampleResolves To
Exact22.3.0 or v22.3.0That exact version
Major.minor22.3Latest patch of 22.3.x
Major22Latest version of 22.x.x
LTSlts or lts/*Latest LTS release

Per-Project Versions

Option 1: Corral setting

corral project set my-worker node-version 22

Option 2: .node-version file in your project directory:

22.3.0

Option 3: .nvmrc file in your project directory:

22

Corral respects these files automatically. If you’re already using .node-version or .nvmrc with another version manager, Corral will honor them without any extra configuration.

Setting a Global Default

corral settings set default-node-version 22

This version is used when no project-specific version is configured. Clear it with:

corral settings set default-node-version none

Running Commands

Run any command using the resolved Node.js version for the current directory:

corral exec node -v
corral exec npx vitest

Shorthand commands for npm and npx:

corral npm install
corral npx wrangler deploy

Override the version for a single command:

corral exec --node-version 20 node -v

Or via environment variable:

CORRAL_NODE_VERSION=20 corral exec node -v

Shell Shims

For seamless integration with your terminal workflow, install shell shims that make node, npm, npx, and cpm automatically use Corral:

corral install-shims

This creates lightweight scripts that delegate to corral exec, in two directories:

DirectoryContents
~/.corral/shims/node, npm, npx
~/.corral/bin/cpm

They’re separate because the first three shadow commands you may already have, and cpm doesn’t. When Corral steps aside (see below) it removes its shadowing shims from the handed-off command’s PATH so a nested node reaches your own binary directly — and cpm, sitting elsewhere, keeps working.

To add both to your PATH:

corral install-shims --patch-profile

This adds them to your shell profile (~/.zshrc, ~/.bashrc, etc.). After reloading your shell:

# Uses the Corral-resolved version automatically
node -v
npm install
npx vitest

# cpm is a shorthand for `corral pm` — use any package manager syntax
cpm install
cpm add -D vitest

To remove the shims:

corral uninstall-shims

You can also install and manage shims from the macOS app’s Node.js Manager.

Upgrading from an older Corral

Earlier versions put all four shims in ~/.corral/bin/. If you installed shims back then, nothing breaks — Corral resolves your pinned Node against a PATH with both of its own shim directories removed, so node, npm, and npx keep working from the old location exactly as before.

Corral moves them for you the next time the background service starts, or the next time you run corral update. It rewrites the three scripts into ~/.corral/shims/ and updates the block it owns in your shell profile to name both directories. Nothing else in your profile is touched.

One case it deliberately leaves alone: if you installed the shims but put them on your PATH yourself — no Corral-managed block in your profile — moving the files would take them off your PATH, and adding an entry you never asked for isn’t Corral’s call. Run this to convert by hand:

corral install-shims --patch-profile

Once it has moved them, corral doctor in a terminal you already had open will say your shell predates the change — that’s expected, and the fix is a new terminal, not a re-install. The command it used to suggest there did nothing, because your profile was already correct.

To check which layout you’re on:

corral doctor   # the "shims" row names the layout, not just "installed / not installed"

The macOS app surfaces the same thing: the shim card in the Node.js Manager reappears when your shims are in the old location.

What happens when Pro isn’t active

The shims sit on your PATH permanently, so every node, npm, and npx you type goes through Corral — whether or not the app is running.

That means Corral has to stay out of the way when it can’t help. Pro buys Corral-managed version resolution, not permission to run npm. If your license lapses, expires, hasn’t checked in recently enough, or you simply never had Pro, the shims hand the command straight to your system’s own node / npm / npx and print one line explaining why:

  ⚠  Corral Pro couldn't be verified — running your system npm instead.
     Last verified 18 days ago.
     Corral revalidates every 24 hours while running; offline, a license is good for 14 days.
     Fix: corral license refresh

Your toolchain keeps working. The notice appears only in an interactive terminal, so build scripts and CI jobs get clean output.

cpm is the exception — it shadows no system command, so there is nothing to hand off to and it reports that it’s unavailable.

To check where you stand:

corral doctor          # includes a license row and a shims-vs-Pro warning
corral license status  # includes the offline check-in countdown
corral license refresh # force a check-in now

Corporate proxies (custom CA certificates)

If you work behind a corporate TLS-intercepting proxy (common at large companies), HTTPS traffic is re-signed with a private corporate root CA. macOS trusts that CA, so browsers work — but Node.js ships its own bundled certificate list and ignores the macOS keychain, so the Node tooling Corral runs fails with errors like:

SELF_SIGNED_CERT_IN_CHAIN
UNABLE_TO_VERIFY_LEAF_SIGNATURE

This breaks npm install, wrangler dev, dependency updates — anything that fetches over HTTPS.

Corral fixes this automatically. On startup (and on demand) it detects the corporate root CAs your Mac already trusts and:

  • points NODE_EXTRA_CA_CERTS at them for every Node process it spawns, and
  • trusts them for its own downloads (the Node toolchain, cloudflared, self-update).

It only ever trusts roots the OS already trusts, and it’s a complete no-op on a machine with no corporate CAs — so there’s nothing to configure in the common case. If you already set NODE_EXTRA_CA_CERTS yourself, Corral folds your file in rather than overriding it.

The feature is on by default. You can see how many roots were detected — and turn it off, or re-scan after IT installs a new certificate — under Settings → Network & Security → Corporate proxy support. See macOS App Settings.

// Last updated 2026-08-11