我把 nvm、jenv、pyenv 全卸了:一个 Rust 单文件管完 40+ 开发工具
先看我卸载前的电脑,同时装着这些:
- nvm:管 node(Windows 上还得换成另一个项目 nvm-windows)
- jenv:管 java(Windows 没有原生实现,要么 git-bash 硬凑,要么 WSL)
- pyenv:管 python(Windows 又是另一个第三方移植 pyenv-win)
- sdkman:管 maven/gradle
四套工具、四种语法、四个目录体系。nvm use、jenv local、pyenv shell------切个版本之前,脑子得先查一次表。
如果你是纯前端或纯后端,单一生态里这些工具其实够用。但如果你和我一样是全栈,公司老项目 Java 8、新服务 Java 21,上午 node 20 下午 node 16,Python 还得再管一套虚拟环境------多套管理器的摩擦成本会越攒越高。
这篇文章记录我最近两个月的重构:用一个小工具把这几摊合成了一摊,以及过程中踩过的坑。
一、三个让我下决心重构的瞬间
1. nvm 切版本,全局包集体失踪
nvm 每个版本是独立目录,npm i -g 装的全局包不跨版本共享。node 16 切到 20,pnpm、typescript 全没了,切一次装一次。江湖上有很多同步脚本,但每次换机器我都要重新折腾一遍。
2. jenv 没有 Windows 原生版,环境变成两套皮
公司的 Windows 机上,我一度用 WSL 跑 jenv。问题来了:IDE 的集成终端是 PowerShell,项目构建脚本跑在 WSL 里,JAVA_HOME 两边各改各的,经常出现 IDE 里 Java 21、终端里 Java 8 的精神分裂现场。最后我放弃了 jenv,回到手动改系统环境变量------一年切不了两次的人可以这么凑合,全栈不行。
3. 新同事入职,环境对齐花了一整天
.nvmrc 只管 node。Java 8 还是 21、Python 用哪个版本、maven 装不装,全靠 README 口头约定。新人第一天基本耗在配环境上,第二天还可能冒出一句"我这里明明是好的啊"。
三个问题指向同一个根因:版本管理是按语言切碎的,而项目是按业务聚合的。
二、现在的方案:sdkm
GitHub 上翻到的开源项目:sdkmate (命令叫 sdkm),Rust 写的,编译产物是一个 4MB 单文件,Windows / macOS / Linux 全平台原生,不用 WSL。
仓库:https://github.com/borenchan/sdkmate(开源,Apache-2.0)
它把自己定位成"全栈工程师的通用 SDK 管理器":内置 java、node、python、go、maven、bun、pnpm、deno、uv、claude-code、cmake、gh、helm、terraform 等 14 个工具开箱直装,累计覆盖 40+ 种工具。
三步上手
bash
# 1. 下载对应平台的压缩包,解压出 4MB 可执行文件,扔进 PATH
# 2. 初始化(Windows 用管理员终端,要写系统环境变量)
sdkm init
# 3. 装东西。版本号只写大版本,自动匹配最新的 21.x
sdkm install java 21
init 会自动配 PATH、注入 shell hook------bash / zsh / fish / PowerShell 都支持,PowerShell 还会同时注入 PS7 和 PS5.1 两个 profile。

三档作用域,这是我认为的杀手级设计
bash
sdkm switch java 21 # 全局:全机器默认
sdkm use java 8 # 项目:版本钉进当前目录的 .sdkm.toml
sdkm use node 18 --shell # 临时:只对当前终端会话生效
use 是项目级的:进目录自动切,离开自动还原。配置文件改动支持热更新,改完按一下回车就生效,不用重开终端。
我的用法:全局挂最新版,老项目钉旧版,想试新版本就开个临时会话,关掉即走。

项目版本进 git,团队对齐不再是口头约定
.sdkm.toml 可以直接提交进仓库:
bash
# .sdkm.toml ------ 提交进 git
[sdks]
java = "8"
node = "16"
同事 clone 下来跑一遍 sdkm init,进目录版本自动对齐。第三节的坑就这么填了。
Windows 被当成一等公民
这点值得单独说:全局切换之后,已经开着的 IDE 也能感知到新版本 。实现上是写系统环境变量后广播 WM_SETTINGCHANGE------Windows 开发者懂的都懂,绝大多数同类工具切完都得重开终端甚至重开 IDE。我在公司 Windows、家里 Mac 两边写,体验完全一致,这是我留在它这的最核心原因。
挑版本像刷菜单
bash
sdkm list node -r # 打开 TUI
方向键翻 860 个 node 版本,看中按 i 安装,已装的按 s 切换。不用再官网翻版本号复制链接了。

内置 40+ 不够?自己注册
GitHub Releases 标准分发的工具,一行命令注册进来,版本解析、平台识别、直链下载全自动:
bash
sdkm config add-sdk mycli --version-url https://github.com/xxx/mycli/releases
我把公司内部的一个 CLI 也挂进去了,统一管理。

三、和同类工具的诚实对比
| 工具 | 平台 | 覆盖 | 项目级切换 | 备注 |
|---|---|---|---|---|
| nvm | macOS/Linux | 仅 node | .nvmrc | Windows 是另一个项目 nvm-windows,行为有差异 |
| jenv | macOS/Linux(Win 需 git-bash) | 仅 java | .java-version | 无原生 Windows 实现 |
| pyenv | macOS/Linux(Win 有第三方移植) | 仅 python | .python-version | 同上,社区维护质量参差 |
| mise | macOS/Linux(Windows 实验性) | 多语言 | .mise.toml | 功能最全、社区最大,文档英文 |
| sdkm | 三平台原生 | 40+(内置14) | .sdkm.toml | 4MB 单文件,文档全中文 |
一句话版:mise 是这个赛道的成熟标杆,功能比 sdkm 全;我缺的是 Windows 原生和中文文档这口气,sdkm 正好补上。作者自己在 README 里写了"你用 mise 用得顺就没必要换",这股诚实劲儿反而让我信了几分。
四、缺点也摆出来
不讲情怀,两个月的真实体验:
- Windows 上
init/switch需要管理员权限,普通终端会失败 - 生态和 mise 没法比,插件、社区问答都少,遇到问题主要靠文档和 issue
- 项目级 / 临时级切换依赖
sdkm init注入的 hook,没注入的话只有全局切换生效 - 单语言重度用户没必要折腾:只写前端的,nvm 用得好好的就别换了
五、总结:适合谁
- ✅ 全栈 / 多语言党:一套命令 + 一套肌肉记忆
- ✅ Windows 开发者:原生支持,不用 WSL 凑合
- ✅ 经常接手老项目的:项目级切换 + 版本进 git
- ❌ 单语言重度用户、mise 老用户:不必折腾
两个月用下来,它没有让我惊艳,但让我省心------对环境管理工具来说,省心就是最高评价。
仓库在这:https://github.com/borenchan/sdkmate,开源免费,文档全中文。觉得思路有意思的话给作者点个 star,换新电脑配环境可以直接抄。
最后评论区聊聊:**你电脑上现在装了几个版本管理器?**我先来:重构前 4 个,现在 0 个(都卸了,一个 sdkm 管完)。