Bug Fixes
- `nvm_alias`, `nvm_version_path`: reject `..` path components
- `nvm_get_make_jobs`: count cores on platforms the `case` does not name
- `nvm-exec`: improve the no-version failure message
- `nvm use`: do not clobber `man`'s default search path (#3890)
- `nvm_err`, `nvm_err_with_colors`: do not fail when stderr is closed (#3907)
- `nvm_hash_reset`: only run `hash -r` where the shell supports it
- `nvm_alias`: unset zsh's `extendedglob` while reading an alias file (#3891)
- zsh: restore `nomatch` and `markdirs` rather than clobbering them
- `nvm --help`: render the set-colors legend in color (#3915)
- `nvm unload`: drop the undefined `nvm_format_help_message_colors`
- `nvm_get_mirror`: allow ports, userinfo, IPv6 hosts, and percent-encoding
- `nvm_sanitize_auth_header`: allow `~`, completing RFC 7235 `token68` (#3751)
Refactors
- `nvm --help`: extract the set-colors legend into `nvm_print_color_legend`
Performance
- Optimize nvm_tree_contains_path with in-memory POSIX parent-walk (#3912)
Docs
- [readme] document platforms with no official node binaries
- `install.sh`: Fix missing words in bash/zsh completion message (#3887)
- Remove stray closing HTML tag (#3919)
Misc
- [meta] remove CLAUDE.md symlink in favor of AGENTS.md (#3928)
- [meta] add `release-notes.sh`, the release notes generator
Tests
- homebrew/actions changed their default branch
- [actions] WSL: pin every distribution, and test the newest of each line
- `nvm_print_color_legend`: look up the function with `PATH` emptied
- `nvm_print_color_legend`: check for the function, not a same-named file
- `nvm_print_color_legend`: fix the `fast` suite on GNU userlands
- [actions] `release.yml`: provide `GH_TOKEN` so release-notes PR lookup can run
New Stuff
- `nvm install`: serialize concurrent installs of the same version
- `nvm install`: add `NVM_NO_SOURCE_FALLBACK` to disable the source fallback
Robustness
- `nvm install`: reject a structurally broken installed version
- `nvm_install_binary_extract`: replace a broken version dir atomically
- `install.sh`: `nvm_download`: avoid `eval` so arguments aren't re-parsed by the shell
Docs
- [readme] link every referenced person and project to its canonical page
Misc
- [Dev Deps] update `markdown-link-check`
Tests
- install_nvm_from_git: don't fail when master is at the latest release tag
urchin only executes test files that have the executable bit, silently skipping the rest,
and `npm run test:check-exec` would catch non-executable ones, but no workflow ran it -
so several test files have never actually run.
Make all of them executable, and fix the ones that were broken:
- the io.js source-install tests, skipped since 2016: io.js requires python 2 and gcc <= 5,
so they now skip on toolchains that can not compile it,
and a new gcc:4.9-container CI job runs them unmodified -
resolving, downloading, checksumming, and compiling io.js for real.
New `fake source` variants exercise nvm's source pipeline everywhere -
cache lookup, offline resolution, extraction, configure, make, make install, activation -
via a tiny fake source tree seeded into the download cache and installed with `--offline`.
Also strengthen the `nvm run | grep` assertions with `--silent`,
since the version banner used to satisfy the grep even when the built binary could not run,
and give the final assertions the `die` they always meant to call.
- `nvm uninstall ... incorrect file permissions fails nicely`, parked in 2025 as failing:
`sudo npm` resets PATH, so node 5's npm crashed under the system node.
The permissions check only trips on files that are neither writable nor self-owned,
and that precondition only needs `sudo touch` - not npm, jspm, or the network -
so use that, against a fake installed version,
and skip only where passwordless sudo does not exist.
- `nvm install --offline`: `nvm ls | tail -1` always grabbed an alias line, never a version;
use `nvm_ls` and skip its trailing `system <version>` line.
- `nvm exec ... help should not parse`: in a BRE, `[options]` is a bracket expression,
so the grep could never match node's literal `Usage: node [options]` output.
- `nvm use ... nvmrc containing not installed version`: current output once again matches its expectations verbatim; no changes needed.
Rewrite `test:check-exec` in POSIX sh - npm runs scripts with /bin/sh, which is dash on Ubuntu,
where the previous `[[`/`$'\n'` bashisms would break;
match by extension, so that filenames containing dots can not dodge the check;
and disable git's `core.quotePath` mangling of the non-ASCII test filenames.
Then wire it into the lint workflow.
New Stuff
- `install.sh`: add `$ZDOTDIR` to zsh search (#3458)
Fixes
- `reinstall-packages`: do not reinstall corepack (#3544)
- avoid bash-specific syntax (#3499)
- `install-latest-npm`: npm v11 is out
- `nvm_install_latest_npm`: avoid unbound variable (#3447)
- give a more helpful message when `lts` alias is mistakenly used (#3441)
- `nvm ls`, `nvm alias`, `nvm install`: error when an LTS name is invalid
- `nvm_normalize_lts`: error when an LTS name is not lowercase (#3417)
Documentation
- [readme] update link
- [readme] fix `--no-use` example (#3479)
- [readme] update copyright notice (#3507)
- [readme] note zsh-nvm's AUTO_USE option (#2670)
- [readme] add note about reloading zshrc after editing (#3052)
- [readme] Update shell profile file install notes (#2241)
- [readme] add docker tips (#2318)
- [readme] remove `avn` from readme (#3469)
- [readme] fnm -> nvm.fish (#2541)
Refactors
- prefer `case` over if/else chains
- combine `sed -e` invocations/arguments
Tests
- `nvm exec`/`nvm run`: add `--silent` tests (#1259)
- [actions] release test needs git tags
- migrate `installation_iojs` test suite to GitHub Actions (#3476)
- Migrate slow test suite from Travis CI (#3470)
- temporarily skip this failing travis test to unblock progress
- [actions] TOC: use latest LTS node
- `install.sh`: clean up `nvm_detect_profile` tests
- `nvm_detect_profile`: refactor (#3467)
- run urchin tests on pull requests (#3466)
- update mocks
- ensure that unit tests use only mocked LTS names
- [actions] use `node/install` instead of `node/run`
Meta
- disable blank issues
- update issue template
- add DCO (#3456)
- Rename .github/ISSUE_TEMPLATE.md to .github/ISSUE_TEMPLATE/ISSUE_TEMPLATE.md (#3454)