Toolmingo
Guides11 min read

NVM Cheat Sheet: Node Version Manager Commands and Usage

Complete NVM (Node Version Manager) reference — install, switch, and manage Node.js versions on Linux, macOS, and Windows. Includes quick reference, .nvmrc workflow, and common mistakes.

NVM lets you install and switch between multiple Node.js versions on the same machine — essential for working on projects that require different Node versions. This reference covers every command you need, from first install to CI setup.

Quick reference

The 25 operations that cover 90% of everyday NVM use.

Command What it does
nvm install node Install the latest Node.js
nvm install 20 Install Node.js 20 (latest patch)
nvm install 20.15.1 Install a specific version
nvm use 20 Switch to Node 20 in current shell
nvm use --lts Switch to the latest LTS version
nvm current Show the active Node.js version
nvm ls List all installed versions
nvm ls-remote List all available versions
nvm ls-remote --lts List available LTS versions
nvm alias default 20 Set default version for new shells
nvm alias default node Set latest as default
nvm uninstall 18 Remove a Node.js version
nvm run 18 app.js Run a file with a specific version
nvm exec 18 npm test Run a command with a specific version
nvm which 20 Show path to Node.js binary
nvm install --reinstall-packages-from=18 Install version + migrate global packages
nvm use Auto-detect version from .nvmrc
nvm install Install version from .nvmrc
nvm alias lts/* 20 Create a named alias
nvm unalias myalias Remove a named alias
nvm cache clear Clear the NVM download cache
nvm deactivate Reset PATH to system Node
nvm version-remote 18 Show latest patch for Node 18
nvm use system Switch to system-installed Node
node -v && npm -v Verify active Node and npm version

Installation

Linux and macOS

Install via the official install script:

# Install latest version of NVM
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.7/install.sh | bash

# Or with wget
wget -qO- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.7/install.sh | bash

The script appends this to your shell config (~/.bashrc, ~/.zshrc, or ~/.profile):

export NVM_DIR="$HOME/.nvm"
[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh"
[ -s "$NVM_DIR/bash_completion" ] && \. "$NVM_DIR/bash_completion"

Reload your shell:

source ~/.bashrc   # or ~/.zshrc
nvm --version      # verify: 0.39.7

Windows

On Windows, use nvm-windows (a separate project):

  1. Download the installer from github.com/coreybutler/nvm-windows/releases
  2. Run nvm-setup.exe
  3. Open a new terminal (as Administrator for first use)
nvm version          # verify installation
nvm install 20       # install Node 20
nvm use 20           # activate it
node -v              # v20.x.x

Note: nvm-windows has slightly different syntax. This cheat sheet covers POSIX nvm; nvm-windows commands are mostly the same but check its README for differences.

Installing Node.js versions

# Install latest stable release
nvm install node

# Install latest LTS (Long Term Support) — recommended for production
nvm install --lts

# Install a specific major version (latest patch for that major)
nvm install 20
nvm install 18
nvm install 22

# Install an exact version
nvm install 20.15.1

# List all remote versions for a major
nvm ls-remote 20

# Install, and migrate global packages from another version
nvm install 20 --reinstall-packages-from=18

LTS vs Current:

Release Description When to use
LTS (Even numbers: 18, 20, 22…) Long-term support, 30 months of patches Production apps, team projects
Current (Odd numbers: 19, 21…) Latest features, shorter support window Trying new Node.js features
Latest Bleeding edge Personal experimentation only

Switching versions

# Switch to a specific version in the current shell
nvm use 20
nvm use 18.20.4

# Switch to the latest LTS
nvm use --lts

# Switch to the latest installed
nvm use node

# Switch to the system Node.js (outside NVM)
nvm use system

# Check the active version
nvm current       # e.g. v20.15.1
node -v           # same output
npm -v            # bundled npm version

nvm use only affects the current terminal session. New terminals use the default.

Setting the default version

# Set default for all new shells
nvm alias default 20
nvm alias default 18.20.4
nvm alias default node       # always use latest installed
nvm alias default --lts      # always use latest LTS

# Create a named alias
nvm alias production 20.15.1
nvm use production

# List all aliases
nvm alias

# Remove an alias
nvm unalias production

Listing versions

# List installed versions
nvm ls

# Example output:
#        v18.20.4
# ->     v20.15.1    (current)
#        v22.5.0
# default -> 20 (-> v20.15.1)
# lts/* -> lts/iron (-> v20.15.1)

# List all available remote versions
nvm ls-remote

# List available LTS versions only
nvm ls-remote --lts

# List available LTS versions for Node 20
nvm ls-remote 20 --lts

# Find the latest remote version for a major
nvm version-remote 20    # v20.15.1

The .nvmrc file

.nvmrc is a file at the root of your project specifying the required Node.js version. It makes version switching automatic:

# Create .nvmrc
echo "20" > .nvmrc
# or exact version
echo "20.15.1" > .nvmrc
# or LTS name
echo "lts/iron" > .nvmrc
# In the project directory — install and use the version from .nvmrc
nvm install   # installs if not present
nvm use       # switches to it

Automatically switch on cd (bash):

Add to ~/.bashrc:

cdnvm() {
  command cd "$@" || return $?
  nvm_path="$(nvm_find_up .nvmrc | tr -d '\n')"
  if [[ ! $nvm_path = *[^[:space:]]* ]]; then
    declare default_version
    default_version="$(nvm version default)"
    if [[ $default_version == "N/A" ]]; then
      nvm use default
    elif [[ $(nvm current) != "$default_version" ]]; then
      nvm use default
    fi
  elif [[ -s "$nvm_path/.nvmrc" && -r "$nvm_path/.nvmrc" ]]; then
    declare nvm_version
    nvm_version=$(<"$nvm_path/.nvmrc")
    declare locally_resolved_nvm_version
    locally_resolved_nvm_version="$(nvm ls --no-colors "$nvm_version" | tail -1 | tr -d '\->*' | tr -d '[:space:]')"
    if [[ "$locally_resolved_nvm_version" == "N/A" ]]; then
      nvm install "$nvm_version"
    elif [[ $(nvm current) != "$locally_resolved_nvm_version" ]]; then
      nvm use "$nvm_version"
    fi
  fi
}
alias cd='cdnvm'
cdnvm "$PWD"

Automatically switch on cd (zsh with zsh-nvm plugin):

# In ~/.zshrc
export NVM_AUTO_USE=true

Or use avn for automatic version switching across all shells.

Running commands with a specific version

Without switching the active version:

# Run a file with Node 18
nvm run 18 server.js
nvm run 18 -- --inspect server.js   # pass Node flags

# Run any command with Node 18
nvm exec 18 npm install
nvm exec 18 npx prettier --write .

# Check which binary would be used
nvm which 18     # /home/user/.nvm/versions/node/v18.20.4/bin/node

Global packages and version migration

Global packages (npm install -g) are per Node.js version. When you switch versions, previously installed globals are not available.

# Install global packages on the new version, migrating from old
nvm install 20 --reinstall-packages-from=18

# Manually reinstall globals on current version
nvm reinstall-packages 18

# List global packages for current version
npm list -g --depth=0

# Check globals for a specific version
nvm exec 18 npm list -g --depth=0

Best practice: Keep global installs minimal. Use npx for one-off tools, and devDependencies for project tools.

NVM in CI/CD

# GitHub Actions
jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version-file: ".nvmrc"  # reads .nvmrc
          cache: "npm"
      - run: npm ci
      - run: npm test

In CI, prefer actions/setup-node over installing NVM — it's faster and already available. The node-version-file: ".nvmrc" option makes it use the same version as local development.

# If you must use NVM in a shell script
export NVM_DIR="$HOME/.nvm"
[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh"

nvm install    # reads .nvmrc
nvm use
npm ci
npm test

Uninstalling versions and NVM itself

# Uninstall a specific Node.js version
nvm uninstall 18
nvm uninstall 18.20.4

# Deactivate NVM in the current shell (reset PATH)
nvm deactivate

# Uninstall NVM entirely
rm -rf "$NVM_DIR"
# Then remove the lines NVM added to ~/.bashrc / ~/.zshrc

Performance: speed up NVM shell startup

NVM can slow down shell startup because it sources a shell script on every new terminal. Options:

Option 1: Lazy loading (bash/zsh)

Replace the NVM init lines in your .bashrc/.zshrc with:

# Lazy load NVM — only runs when you first call nvm/node/npm
nvm() {
  unset -f nvm node npm npx
  export NVM_DIR="$HOME/.nvm"
  [ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh"
  nvm "$@"
}
node() {
  unset -f nvm node npm npx
  export NVM_DIR="$HOME/.nvm"
  [ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh"
  node "$@"
}
npm() { node; npm "$@"; }
npx() { node; npx "$@"; }

Option 2: Switch to fnm (Fast Node Manager)

fnm is NVM-compatible (reads .nvmrc) and written in Rust — 40× faster startup:

# Install fnm
curl -fsSL https://fnm.vercel.app/install | bash

# Same commands as NVM
fnm install 20
fnm use 20
fnm default 20
fnm ls

Common NVM workflows

Starting a new Node.js project:

# Create project directory
mkdir my-project && cd my-project

# Install and pin a Node.js version
nvm install 20
nvm use 20
echo "20" > .nvmrc     # pin for the team

# Initialize project
npm init -y
git init
echo "node_modules/" >> .gitignore

Troubleshooting a version-specific bug:

# Test with multiple versions without changing default
nvm exec 18 npm test
nvm exec 20 npm test
nvm exec 22 npm test

Upgrading Node.js version on a project:

# Install new version
nvm install 22

# Install project dependencies
nvm exec 22 npm install

# Run tests
nvm exec 22 npm test

# If tests pass, update .nvmrc and set as default
echo "22" > .nvmrc
nvm alias default 22
nvm use 22

# Update package.json engines field
# "engines": { "node": ">=22.0.0" }

NVM vs alternatives

Tool Language Speed .nvmrc support Windows Notes
nvm Shell Slow startup Yes No (nvm-windows is separate) Most widely used
fnm Rust Fast Yes Yes Drop-in NVM replacement
volta Rust Fast Per-project package.json Yes Manages npm/yarn too
asdf Shell Medium .tool-versions Limited Manages many languages
n Shell Fast .node-version No Simpler, no shell patching
nvm-windows Go Medium Yes Yes Windows-only, different codebase

7 common mistakes

1. Forgetting that nvm use is session-scoped

# BAD — only affects THIS terminal
nvm use 20
# New terminal still uses default version

# GOOD — set the default
nvm alias default 20

2. Installing global packages then switching versions

# BAD — global package lost after switching
nvm use 18
npm install -g typescript
nvm use 20
tsc --version  # command not found!

# GOOD — reinstall globals or use npx
nvm install 20 --reinstall-packages-from=18
# or use npx for one-offs:
npx tsc --version

3. Not committing .nvmrc

# BAD — teammates use different Node.js versions
# (no .nvmrc in repo)

# GOOD — commit .nvmrc so everyone uses the same version
echo "20" > .nvmrc
git add .nvmrc
git commit -m "chore: pin Node.js version to 20"

4. Using nvm install node instead of a specific version

# RISKY — "node" changes over time
nvm install node

# BETTER — pin a major version
nvm install 20       # always gets latest 20.x.x
nvm install 20.15.1  # exact pin

5. Slow shell startup (not lazy-loading)

# BAD — sources NVM on every shell start (50-500ms delay)
# (default install)

# GOOD — lazy load or switch to fnm
# See "Performance" section above

6. Running NVM in non-interactive scripts without sourcing

#!/bin/bash
# BAD — nvm not available in non-interactive shells
nvm use 20  # nvm: command not found

# GOOD — source nvm first
#!/bin/bash
export NVM_DIR="$HOME/.nvm"
[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh"
nvm use 20

7. Not updating NVM itself

# NVM is updated separately from Node.js
# To update NVM, re-run the install script — it upgrades in-place
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.7/install.sh | bash

# Check current NVM version
nvm --version

6 FAQ

Q: What is the difference between NVM and Node.js?

Node.js is the JavaScript runtime. NVM is a tool to install and manage multiple Node.js versions. You install NVM once, then use it to install different versions of Node.js. Think of NVM as a package manager for Node.js itself.

Q: Should I use LTS or Current?

Use LTS for anything that needs to run reliably — production servers, team projects, CI/CD. LTS versions receive security and bug fixes for 30 months. Use Current only to try out new Node.js features in personal projects.

Q: Why does nvm use not persist across terminal sessions?

nvm use only modifies the PATH in the current shell process. When you open a new terminal, it inherits the default. Use nvm alias default <version> to permanently set what new terminals get.

Q: Can I use NVM and Volta together?

Yes, but they can conflict if both modify PATH in your shell config. Pick one version manager and use it consistently. Volta is particularly good for projects where you want to lock both Node.js and npm/yarn versions without shell magic.

Q: How do I use NVM in a Docker container?

For Docker, skip NVM. Instead, use the official Node.js image:

FROM node:20-alpine
WORKDIR /app
COPY package*.json .
RUN npm ci
COPY . .
CMD ["node", "server.js"]

If you truly need NVM inside Docker (e.g., testing across versions), install it in the Dockerfile:

FROM ubuntu:22.04
ENV NVM_DIR /root/.nvm
RUN curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.7/install.sh | bash \
    && . "$NVM_DIR/nvm.sh" \
    && nvm install 20 \
    && nvm alias default 20
ENV PATH $NVM_DIR/versions/node/v20.15.1/bin:$PATH

Q: What is .node-version vs .nvmrc?

.nvmrc is the NVM standard; .node-version is used by tools like n and volta. NVM reads .nvmrc by default. Many tools (fnm, asdf, volta, GitHub Actions setup-node) support both formats. Use .nvmrc for broadest compatibility.

Related tools

Keep reading

All Toolmingotools are free & run in your browser

No sign-up, no upload, no watermark. Your files never leave your device.

Browse all tools