## What
Reworks the bespoke `etc/scripts/find-node` and its `Makefile`
interaction so node discovery works out of the box on Linux and macOS,
is optionally friendly to version managers, and stays sympathetic to
people who just use system node.
### Before
- Only ever looked at `PATH`, plus a vestigial
`/opt/compiler-explorer/node` hardcode (an affordance for one dev's
local setup, unused by the live site).
- Duplicated the required node version in three places (`find-node` had
`22` twice; `.node-version`; `package.json` `engines`).
- Silently fell back *past* an unusable `NODE_DIR` to whatever else it
found.
- nvm users got whatever default was active, not the version this repo
pins.
- Nagged on any version that wasn't exactly `22.x`, even newer ones.
### After — clear, permissive resolution order
1. **`$NODE_DIR/bin/node`** — explicit override, now authoritative. If
it's set but missing/too old you get a clear error instead of a silent
fallback.
2. **`node`/`nodejs` on `PATH`** — covers system node *and* any version
manager with shell integration (fnm, asdf, nodenv, volta, an active
nvm). Zero extra steps on a well-configured machine.
3. **Manager rescue** — only when PATH node is absent or below the
minimum: source `nvm` and ask for the pinned version (the one manager
that's a shell function rather than a PATH binary), then try
`fnm`/`nodenv`/`asdf`. Each branch is inert unless that tool is
installed, so nobody is pushed onto a manager.
Other changes:
- **Single source of truth**: the minimum major now comes solely from
`.node-version` (the same file the managers read). Newer majors are
always fine — the "only tested against v22.x" warning is dropped.
- **`Makefile`**: `.node-bin` now also depends on `.node-version`, so
bumping the pin re-resolves node instead of serving a stale cache. The
lazy-dotfile pattern (so failures abort `make` and `make help` pays
nothing) is kept.
- **`README`**: documents the PATH-first + manager-rescue behaviour.
## Testing
- `shellcheck` clean.
- Verified: PATH discovery, valid/bogus `NODE_DIR`, nvm rescue (shadowed
`node`+`nodejs` with v18 shims → skipped them and resolved v22.22 via
nvm), too-old fallthrough, no-node/no-manager failure message, and `make
info` end-to-end.
- `fnm` branch is logically straightforward but was not exercised (no
fnm on the test box) — worth a smoke test if you have one.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
---------
Co-authored-by: mattgodbolt-molty <mattgodbolt-molty@users.noreply.github.com>
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-authored-by: Matt Godbolt <matt@godbolt.org>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Raises Compiler Explorer's minimum Node version from 20 to 22, aligning
the declared floor with what production actually runs (Node 22.13.1
across the fleet).
## Why
- Production already runs Node 22.13.1 everywhere; the declared floor
(`>=20`) lagged reality.
- It's a prerequisite for upcoming dependency majors — commander 15
requires Node >=22.12.
## Changes
- `package.json`: `engines.node` `>=20.0.0` → `>=22.0.0`.
- `etc/scripts/find-node`: `NODE_MIN_VERSION` `20` → `22`.
- `.github/workflows/test-and-deploy.yml`: the `build_minimum_support`
job moves from Node 20.18.2 to 22.12.0 (the genuine floor), since
`find-node` now rejects Node <22.
Split out from the major-dependency PR (#8761) so it can land
independently. #8761 will rebase cleanly on top once this merges.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
---------
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
`which` isn't in POSIX and some Linux distributions (e.g. Debian,
Gentoo) are trying to remove it from their base installs. See
https://lwn.net/Articles/874049/.
If system's node is overriden by something in PATH, having NODE_DIR
empty will cause the script to still use node found in /bin/.
Only consider the first case if NODE_DIR is not empty.
By default FreeBSD does not have the Bourne-again shell (Bash)
installed. Therefore, the system fails to execute two ``find'' scripts
(etc/scripts/find-node and etc/scripts/find-yarn) running by the
Makefile within the `.node-bin` and `.yarn-bin` targets.
I see nothing Bash-specific in those scripts. Also I believe that
`[[ expression ]]` commands in those particular cases can be safely
replaced with the `test` built-in commands.
With these changes I can now run a local ``Compiler explorer'' instance
on FreeBSD.
Signed-off-by: Ruslan Garipov <ruslanngaripov@gmail.com>