nvm
CLI Toolnvm-sh/nvm
POSIX-compliant bash script to manage multiple active Node.js versions.
Overview
nvm is a version manager for Node.js that allows quick installation and switching between multiple active versions from the command line. It works across POSIX-compliant shells including bash, zsh, ksh, and sh on Unix, macOS, and Windows WSL. It supports per-project versioning with .nvmrc files and offers features like offline installs and mirror customization.
README Preview
\n \n \n \n \n\n\n\n# Node Version Manager [][3] [][4] [](https://bestpractices.dev/projects/684)\n\n\n\n\n## Table of Contents\n\n- [Intro](#intro)\n- [About](#about)\n- [Installing and Updating](#installing-and-updating)\n - [Install & Update Script](#install--update-script)\n - [Additional Notes](#additional-notes)\n - [Installing in Docker](#installing-in-docker)\n - [Installing in Docker for CICD-Jobs](#installing-in-docker-for-cicd-jobs)\n - [Troubleshooting on Linux](#troubleshooting-on-linux)\n - [Troubleshooting on macOS](#troubleshooting-on-macos)\n - [Ansible](#ansible)\n - [Verify Installation](#verify-installation)\n - [Important Notes](#important-notes)\n - [Git Install](#git-install)\n - [Manual Install](#manual-install)\n - [Manual Upgrade](#manual-upgrade)\n- [Usage](#usage)\n - [Long-term Support](#long-term-support)\n - [Migrating Global Packages While Installing](#migrating-global-packages-while-installing)\n - [Migrating Global Packages Between Installed Versions](#migrating-global-packages-between-installed-versions)\n - [Offline Install](#offline-install)\n - [Default Global Packages From File While Installing](#default-global-packages-from-file-while-installing)\n - [io.js](#iojs)\n - [System Version of Node](#system-version-of-node)\n - [Listing Versions](#listing-versions)\n - [Setting Custom Colors](#setting-custom-colors)\n - [Persisting custom colors](#persisting-custom-colors)\n - [Suppressing colorized output](#suppressing-colorized-output)\n - [Restoring PATH](#restoring-path)\n - [Set default node version](#set-default-node-version)\n - [Use a mirror of node binaries](#use-a-mirror-of-node-binaries)\n - [Pass Authorization header to mirror](#pass-authorization-header-to-mirror)\n - [.nvmrc](#nvmrc)\n - [Deeper Shell Integration](#deeper-shell-integration)\n - [Calling `nvm use` automatically in a directory with a `.nvmrc` file](#calling-nvm-use-automatically-in-a-directory-w
FAQ (5)
TroubleshootingHow to fix nvm error "cdhist: error: unrecognized arguments: -q" when sourcing nvm.sh in zsh?
This happens because a user-defined cd shell function from cdhist shadows zsh's built-in cd. nvm runs cd -q in zsh, but cdhist does not support the -q flag, causing NVM_DIR to become /.
Upgrade nvm to a release containing the nvm_cd fix, which bypasses user-defined cd functions and calls the shell builtin directly.
Immediate patch: open ~/.nvm/nvm.sh, find nvm_cd(), and change it to:
nvm_cd() {
if nvm_is_zsh; then
builtin cd "$@"
else
command cd "$@"
fi
}
Then reload:
source ~/.nvm/nvm.sh
Temporary workaround for the current shell only:
unset -f cd
source ~/.nvm/nvm.sh
This disables the cdhist cd function until the shell is restarted.
TroubleshootingHow do I fix nvm's install script appending bash_completion to the last line of ~/.bashrc?
This occurs with nvm v0.40.8's installer when ~/.bashrc has no trailing newline and already contains a line matching nvm.sh; the completion line is appended without starting a new line. To repair it, open ~/.bashrc and move the nvm completion snippet onto its own line:
[ -s "$NVM_DIR/bash_completion" ] && \. "$NVM_DIR/bash_completion" # This loads nvm bash_completion
Before rerunning the installer, ensure the file ends with a newline:
[ -n "$(tail -c1 ~/.bashrc)" ] && printf '\n' >> ~/.bashrc
Then rerun the latest nvm installer, which includes the fix to write a newline before appending to a profile that does not already end with one.
TroubleshootingHow do I fix nvm's "not compatible with the npm config prefix option" error on macOS when no separate Node.js installation exists?
This can happen when macOS reports a home-directory path with different capitalization from the actual folder, often after a Time Machine restore or account migration—for example, $HOME is /Users/mitch but the folder is /Users/Mitch. Compare the paths with:
echo "$HOME"
whoami
ls -ld /Users/*
If the capitalization differs, correct the home directory path:
1. Back up your Mac and log out of the affected account.
2. Go to **System Preferences → Users & Groups**.
3. Right-click your user and choose **Advanced Options**.
4. Set **Home directory** to the actual capitalized path, such as /Users/Mitch.
5. Save, restart your Mac, and reopen Terminal.
6. If nvm still reports the prefix for an installed version, run:
nvm use --delete-prefix v14.5.0
Replace v14.5.0 with the Node version installed by nvm. Updating nvm may also display an improved warning for this case; the detection was addressed in nvm PR #2263.
TroubleshootingWhy is nvm making zsh startup slow, and how do I reduce the delay?
The delay is mainly caused by nvm automatically running nvm use default when nvm.sh is sourced. Defer that version selection by sourcing nvm with --no-use.
In ~/.zshrc, replace:
[ -s "$NVM_DIR/nvm.sh" ] && . "$NVM_DIR/nvm.sh"
with:
export NVM_DIR="$HOME/.nvm"
[ -s "$NVM_DIR/nvm.sh" ] && . "$NVM_DIR/nvm.sh" --no-use
[ -s "$NVM_DIR/bash_completion" ] && . "$NVM_DIR/bash_completion"
Restart the shell:
exec zsh
In the issue's benchmarks, normal loading took about 303 ms, while --no-use reduced shell startup to about 75 ms; sourcing nvm itself cost roughly 44 ms, with the remaining time spent on automatic default-version selection.
With --no-use, run the following when you need Node:
nvm use default
Alternatively, lazy-load nvm only when nvm, node, npm, or npx is first called:
export NVM_DIR="$HOME/.nvm"
_lazy_load_nvm() {
unset -f nvm node npm npx
[ -s "$NVM_DIR/nvm.sh" ] && . "$NVM_DIR/nvm.sh"
[ -s "$NVM_DIR/bash_completion" ] && . "$NVM_DIR/bash_completion"
}
nvm() { _lazy_load_nvm; nvm "$@"; }
node() { _lazy_load_nvm; node "$@"; }
npm() { _lazy_load_nvm; npm "$@"; }
npx() { _lazy_load_nvm; npx "$@"; }
Measure startup with:
hyperfine --warmup 3 'zsh -i -c exit'TroubleshootingWhy does nvm installation fail on WSL when Node.js/npm is installed on the Windows host?
**Cause:** nvm's install script calls npm (via nvm_check_global_modules). On WSL, Windows paths are appended to $PATH by default, so npm can resolve to /mnt/c/Program Files/nodejs/npm — a shell script bundled with the Windows Node.js install that executes Windows node.exe. This breaks the installation.
**Workaround 1 — stop Windows PATH leaking into WSL (recommended):**
1. Create/edit /etc/wsl.conf inside WSL:
[interop]
appendWindowsPath = false2. From PowerShell on Windows, run
wsl --shutdown, then reopen your WSL terminal.3. Re-run the nvm install script.
**Workaround 2 — temporarily strip Windows paths just for the install:**
PATH=$(echo "$PATH" | tr ':' '\n' | grep -v '^/mnt/c' | paste -sd: -)
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.3/install.sh | bash
Verify with which npm — it should not point to /mnt/c/.... A fix in nvm itself (skipping npm checks when a Windows node.exe sits next to npm) has been proposed, so upgrading nvm once released may also resolve it.