nvm

CLI Tool

nvm-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)

Troubleshooting
How 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.

GitHub Issue #3835
Troubleshooting
How 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.

GitHub Issue #3951
Troubleshooting
How 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.

GitHub Issue #2261
Troubleshooting
Why 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'

GitHub Issue #3930
Troubleshooting
Why 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 = false

2. 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.

GitHub Issue #3700