nvm logo

nvm

Node.js 版本管理工具,轻松在同一系统上切换多个 Node.js 版本

包管理器Node.js版本管理多版本切换

nvm 是 Node.js 生态中最广泛的版本管理工具,支持在同一台机器上安装、切换和管理多个 Node.js 版本。分为 nvm-sh(macOS/Linux)和 nvm-windows 两个独立项目。

nvm

Node.js 版本管理工具,轻松在同一系统上切换多个 Node.js 版本

技术简介说明

nvm(Node Version Manager)是 Node.js 生态中使用最广泛的版本管理工具,自 2011 年由 creationix 创建以来,已成为前端开发者的基础设施。它解决的核心问题是:在同一台机器上安装、切换和管理多个 Node.js 版本,而无需手动修改系统环境变量。

随着 Node.js 生态发展,nvm 分化为两个独立项目:

  • nvm-sh/nvm:面向 macOS/Linux 的 POSIX shell 脚本实现,由 Node.js 社区维护,截至 2026 年 6 月最新版本为 v0.40.5,仍然活跃开发中。
  • coreybutler/nvm-windows:面向 Windows 的独立实现(Go 语言),由 Corey Butler 主导,目前正向 Runtime(Author Software Inc. 继任项目)过渡。

nvm 的重要性体现在:多版本并行开发、LTS 管理、通过 .nvmrc 统一团队环境、CI/CD 集成等方面。

基本信息

属性nvm-sh(macOS/Linux)nvm-windows(Windows)
GitHub 仓库https://github.com/nvm-sh/nvmhttps://github.com/coreybutler/nvm-windows
最新版本v0.40.5(2026 年 6 月 4 日)v1.2.x(2025 年 1 月发布 v1.2.0)
开源协议MITMIT
实现语言POSIX shell 脚本(Bash)Go 语言
维护者Node.js 社区Corey Butler
项目状态活跃维护过渡阶段(向 Runtime 迁移)
继任项目Runtime by Author Software Inc.

重要提示:nvm-sh 和 nvm-windows 是两个完全独立的项目,代码库、实现方式、命令语法均有差异。搜索文档或排查问题时务必确认使用的是哪个版本。

快速上手

安装

nvm-sh(macOS / Linux)——使用官方安装脚本:

curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.5/install.sh | bash

安装完成后在 shell 配置文件中添加:

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

支持 bash、zsh、fish、dash、ksh 等 POSIX 兼容 shell。官方不推荐通过 Homebrew 安装。

nvm-windows——下载 nvm-setup.exe 安装程序:

  1. 前往 Releases 页面 下载 nvm-setup.exe
  2. 运行安装程序,选择安装路径和 symlink 路径
  3. 以管理员身份打开 CMD 或 PowerShell
nvm version          # 验证安装
nvm list available   # 查看可用版本
nvm install 22.12.0  # 安装指定版本
nvm use 22.12.0      # 使用该版本

v1.2.0+ 注意:部分用户报告安装后存在已知问题,建议查阅 GitHub Issues。遇到问题可回退到 v1.1.x 或使用继任项目 Runtime。

基础配置

.nvmrc 文件——在项目根目录指定 Node.js 版本:

echo "22.12.0" > .nvmrc   # 精确版本
echo "22" > .nvmrc         # 主版本号
echo "lts/jod" > .nvmrc   # LTS 别名
echo "lts/*" > .nvmrc     # 最新 LTS
echo "node" > .nvmrc       # 最新稳定版

团队成员克隆后执行 nvm install && nvm use 即可。

默认版本与环境变量

nvm alias default 22.12.0     # 设置默认版本
 
# 国内用户加速下载
export NVM_NODEJS_ORG_MIRROR=https://npmmirror.com/mirrors/node

最小示例

# 安装并使用
nvm install --lts              # 安装最新 LTS
nvm install 20.18.0            # 安装指定版本
nvm use 22                     # 切换版本
nvm ls                         # 查看已安装版本
nvm ls-remote --lts            # 查看远程可用版本
nvm exec 22 node -e "console.log(process.version)"  # 指定版本运行命令
nvm uninstall 18.19.0          # 卸载版本

核心概念与架构

版本管理机制

nvm 通过目录隔离管理不同版本:

~/.nvm/
├── nvm.sh              # nvm 核心脚本
├── versions/           # Node.js 版本安装目录
│   ├── v20.18.0/
│   │   ├── bin/        # node, npm, npx
│   │   ├── lib/
│   │   └── include/
│   └── v22.12.0/
├── alias/              # 版本别名(default, lts/*, stable)
└── .cache/             # 下载缓存(v0.40.5+ 支持离线安装)

每个版本独立安装在自己的目录中,切换版本时修改当前 shell 的 PATH,将目标版本的 bin 目录置于最前。

Shell 钩子机制

nvm-sh 通过 shell 钩子实现自动版本切换:

  1. cd 钩子:配置后可在 cd 进入含 .nvmrc 目录时自动切换版本
  2. shell 启动:每次打开终端时加载 nvm,设置 PATH 为默认版本
  3. 显式调用nvm use 手动切换,仅影响当前会话
# zsh 自动切换配置
autoload -U add-zsh-hook
load-nvmrc() {
  local nvmrc_path="$(nvm_find_nvmrc)"
  if [ -n "$nvmrc_path" ]; then
    local nvmrc_node_version=$(nvm version "$(cat "${nvmrc_path}")")
    if [ "$nvmrc_node_version" = "N/A" ]; then
      nvm install
    elif [ "$nvmrc_node_version" != "$(nvm version)" ]; then
      nvm use
    fi
  fi
}
add-zsh-hook chpwd load-nvmrc

nvm-windows 采用不同技术方案:

C:\Users\<user>\AppData\Roaming\nvm\   # nvm 安装目录
├── nvm.exe                             # nvm 可执行文件
├── v18.20.4\                           # Node.js 版本目录
├── v20.18.0\
└── v22.12.0\

C:\Program Files\nodejs\                # Symlink → 当前活跃版本

创建 symlink 目录(默认 C:\Program Files\nodejs\)指向当前版本目录,将该 symlink 加入系统 PATH。由于涉及系统目录操作,部分命令需要管理员权限。nvm-windows 还与 Windows 注册表交互,确保环境变量全局生效。

.nvmrc 解析规则

  • 精确版本22.12.0 — 完整语义化版本号
  • 部分版本2222.12 — 匹配已安装的最新小版本
  • LTS 别名lts/jod — 匹配指定代号的 LTS
  • 通配符lts/* — 最新 LTS
  • 关键字node / stable — 最新稳定版

.nvmrc 文件中只应包含版本号字符串,不要添加注释或额外内容。

核心特性

版本安装与切换

nvm install --lts           # 安装最新 LTS
nvm install 22.12.0         # 安装指定版本
nvm use 20                  # 切换已安装版本
nvm use lts/jod             # 按 LTS 别名切换
nvm exec 18 npm run build   # 在指定版本下运行命令

LTS 别名系统

nvm 维护了与 Node.js 官方 LTS 计划同步的别名:

别名对应版本代号状态
lts/jodNode.js 22Jod活跃 LTS(2024.10 - 2027.04)
lts/ironNode.js 20Iron维护 LTS(2023.10 - 2026.04)
lts/hydrogenNode.js 18Hydrogen已 EOL(2025.04 结束)

离线安装(v0.40.5+)

nvm install --offline 允许从本地缓存安装 Node.js,无需网络连接:

# 首次在线安装(自动缓存到 ~/.nvm/.cache/)
nvm install 22.12.0
 
# 后续可从缓存离线安装
nvm install --offline 22.12.0

适用于企业内部网络受限、预打包开发环境镜像、安全隔离网络等场景。

校验和验证

安装时自动验证下载文件的 checksum,确保文件完整性和供应链安全。

全局包管理

每个 Node.js 版本有独立的全局包目录:

nvm exec 22 npm install -g typescript           # 在指定版本下全局安装
nvm reinstall-packages 20                        # 将默认版本的全局包迁移到 20

多架构支持

Apple Silicon Mac 上支持原生 ARM64 和通过 Rosetta 2 运行 x64 版本:

arch -arm64 nvm install 22     # ARM64 原生版本
arch -x86_64 nvm install 22   # x64 版本(Rosetta 2)

生态图

nvm 在 Node.js 工具链中占据基础位置:

Node.js 发布周期(Current / LTS)
         │
         ▼
       nvm(版本安装与切换)
         │
    ┌────┼────┐
    ▼    ▼    ▼
  开发   CI/CD  Docker
  环境   集成   构建
    │    │    │
    └────┼────┘
         ▼
  项目运行(Node.js + pnpm/npm/yarn)

IDE 集成:VS Code 自动检测 .nvmrc;WebStorm 支持配置 nvm 管理的路径;Neovim 通过终端/LSP 集成。

CI/CD:GitHub Actions 的 actions/setup-node 支持 .nvmrc 自动检测;GitLab CI、CircleCI 均预装 nvm。

包管理器协同:pnpm 的全局 store 跨版本共享;npm 随 Node.js 绑定安装;Yarn Classic/Berry 均可运行。

适用场景

多项目并行开发:不同项目使用不同 Node.js 版本,通过 cd 触发 .nvmrc 自动切换:

cd ~/projects/legacy-app   # .nvmrc → 18,自动切换 Node 18
cd ~/projects/main-app     # .nvmrc → 22,自动切换 Node 22 LTS
cd ~/projects/experiment   # .nvmrc → node,自动切换最新版

跨版本测试:库维护者确保代码在多个 Node.js 版本上正常运行:

for version in 18 20 22; do
  nvm use $version
  echo "Testing on Node.js $(node -v)..."
  npm test
done

遗留项目维护:安装旧版本(如 Node 16)支持遗留系统运行。

团队标准化:通过 .nvmrc + package.json engines 字段统一开发环境。

升级评估:安装新版本在隔离 shell 中测试兼容性,发现问题可立即切回稳定版。

开发与工程化

项目配置结构

my-project/
├── .nvmrc              # 开发环境版本
├── .node-version       # fnm/asdf 兼容(可选)
├── .github/workflows/  # CI 测试矩阵
└── package.json        # engines 字段约束

package.json 中配合 engines 约束:

{
  "engines": { "node": ">=20.0.0 <23.0.0" }
}

CI 集成

GitHub Actions(推荐使用 setup-node):

jobs:
  test:
    strategy:
      matrix:
        node-version: [20.x, 22.x]
    steps:
      - uses: actions/setup-node@v4
        with:
          node-version: ${{ matrix.node-version }}
      - run: corepack enable
      - run: pnpm install --frozen-lockfile
      - run: pnpm test

GitLab CI(在 before_script 中使用 nvm):

.test:
  script:
    - curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.5/install.sh | bash
    - export NVM_DIR="$HOME/.nvm" && source $NVM_DIR/nvm.sh
    - nvm install $NODE_VERSION && nvm use $NODE_VERSION
    - pnpm install --frozen-lockfile && pnpm test
 
test-node-20:
  extends: .test
  variables:
    NODE_VERSION: "20"
 
test-node-22:
  extends: .test
  variables:
    NODE_VERSION: "22"

Docker——直接使用官方镜像而非 nvm:

FROM node:22.12.0-alpine AS builder
WORKDIR /app
COPY . .
RUN corepack enable && pnpm install --frozen-lockfile && pnpm build

通过 ARG.nvmrc 同步版本号,保持 Docker 与开发环境一致:

ARG NODE_VERSION
FROM node:${NODE_VERSION}-alpine AS builder
# 构建时传入 .nvmrc 中的版本
docker build --build-arg NODE_VERSION=$(cat .nvmrc) -t my-app .

Monorepo 注意

所有 workspace 共享同一个 Node.js 版本。在根目录维护 .nvmrc,配合 "packageManager" 字段统一管理。

性能与安全

Shell 启动性能

nvm-sh 的主要痛点:shell 启动延迟 200-800 毫秒(需 source 约 8000 行 bash 脚本)。

优化方案——懒加载(首次调用时才加载 nvm):

nvm_lazy_load() {
  unset -f nvm node npm npx
  export NVM_DIR="$HOME/.nvm"
  [ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh"
}
nvm()  { nvm_lazy_load; nvm  "$@"; }
node() { nvm_lazy_load; node "$@"; }
npm()  { nvm_lazy_load; npm  "$@"; }
npx()  { nvm_lazy_load; npx  "$@"; }

若启动延迟是核心痛点,建议考虑 fnm(Rust 实现,启动时间 1-5ms)。

CVE-2026-10796

v0.40.5 修复了下载过程中校验和处理的安全漏洞,可能导致未经验证的二进制文件被使用。所有用户应升级到 v0.40.5+

v0.40.5 其他修复

  • 修复 download_artifact 下载逻辑错误
  • 修复 get_checksum 在部分系统上的兼容性问题
  • 改进安装脚本的健壮性

供应链安全

使用国内镜像时,确保来源可信(npmmirror 为可信镜像,避免使用不明第三方源):

export NVM_NODEJS_ORG_MIRROR=https://npmmirror.com/mirrors/node

验证安装脚本完整性:

curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.5/install.sh | shasum -a 256

技术对比

特性nvmfnmnmiseasdfVolta
语言BashRustBashRustBashRust
平台macOS/Linux跨平台macOS/Linux跨平台macOS/Linux跨平台
Windows❌(nvm-windows 独立)✅ 原生✅(部分)
速度慢(200-800ms)极快(1-5ms)极快极快
.nvmrc✅ 原生✅ 兼容✅ 兼容
多语言❌ 仅 Node.js❌ 仅 Node.js❌ 仅 Node.js❌ 仅 Node.js
离线安装✅ v0.40.5+
社区生态最成熟快速增长小众增长中稳定小众

选型建议

  • 坚持 nvm:团队已广泛使用,需要最成熟的社区支持
  • 选择 fnm:重视启动速度、需要 Windows 原生支持、希望兼容 .nvmrc
  • 选择 mise:需要管理多种语言运行时(Node.js + Python + Ruby 等)
  • 选择 asdf:团队使用多种语言,需要统一插件化版本管理
  • 选择 Volta:需要通过 package.json 实现项目级版本锁定

最佳实践

  1. .nvmrc 始终提交到 Git,推荐使用主版本号(如 22)或精确版本(如 22.12.0),避免 lts/* 导致成员版本不一致

  2. 版本升级流程:先在 CI 测试新版本,再更新 .nvmrcengines 字段,通过 PR 让团队审查

  3. pre-commit 检查——通过 husky 钩子校验 Node.js 版本是否与 .nvmrc 一致:

#!/bin/sh
# .husky/pre-commit
REQUIRED=$(cat .nvmrc)
CURRENT=$(node -v | sed 's/^v//')
if [ "$CURRENT" != "$REQUIRED" ] && [[ ! "$CURRENT" == ${REQUIRED}* ]]; then
  echo "⚠️  Node.js 版本不匹配"
  echo "   期望: $REQUIRED(来自 .nvmrc)"
  echo "   当前: v$CURRENT"
  echo "   请运行: nvm use"
  exit 1
fi
  1. CI 锁定精确版本:CI 中使用精确版本号而非 lts/*,确保构建可重现

  2. 国内镜像:设置 NVM_NODEJS_ORG_MIRROR=https://npmmirror.com/mirrors/node 加速下载

技术局限与边界

nvm-sh 局限

  • 仅支持 POSIX shell,无法在 Windows CMD/PowerShell 运行
  • Shell 启动延迟 200-800ms(有懒加载方案但增加首次命令延迟)
  • 纯 Shell 实现存在性能天花板,无法与 Rust/Go 替代品竞争
  • 首次安装依赖网络(v0.40.5+ 支持离线缓存,但首次仍需下载)

nvm-windows 局限

  • 正过渡到 Runtime 项目,v1.2.0+ 存在已知安装问题,未来方向不明确
  • 创建 symlink 需管理员权限
  • 命令语法与 nvm-sh 有细微差异,跨平台脚本兼容性不佳

共同边界

  • 仅管理 Node.js,不涉及 Python/Ruby/Go 等运行时(需要多语言管理选 mise/asdf)
  • 不管理包管理器版本(通过 corepack 管理)
  • 容器环境中不如直接使用固定版本的 Docker 镜像简洁

学习资源

2026 年现状

nvm-sh 稳定发展:v0.40.5 修复了 CVE-2026-10796 安全漏洞,新增离线安装能力,修复了下载和校验相关 bug。社区活跃,Maintainer 团队稳定,仍然是 macOS/Linux 上使用最广泛的 Node.js 版本管理器。但 shell 脚本的技术实现限制了性能优化空间。

nvm-windows 过渡期:v1.2.x 作为过渡版本引入了改进但也带来安装问题。Runtime 项目将接替 nvm-windows,提供统一的开发环境管理。过渡期内新用户在两者间需要做出选择。

替代品崛起:fnm 凭借跨平台支持、毫秒级速度和 .nvmrc 兼容性持续增长;mise 为多语言团队提供统一管理体验;Volta 通过 package.json 实现项目级锁定。但 nvm 凭借先发优势和庞大用户基数仍占主导地位,大多数教程和 CI 模板仍以 nvm 为主。

建议

  • 现有用户:升级到 v0.40.5 获取安全修复,若启动延迟影响体验可考虑 fnm
  • Windows 用户:关注 Runtime 成熟度,fnm 也是可靠替代
  • 新项目:仅需管理 Node.js 选 nvm 或 fnm,需多语言管理选 mise