更新于

From fnm/Node & Manual Go to mise: Unified Management for uv, Bun, Rust, Node.js, Go


From fnm/Node & Manual Go to mise: Unified Management for uv, Bun, Rust, Node.js, Go

Still using nvm/fnm for Node, rustup for Rust, manual tar extraction for Go, and curl for uv/Bun in 2026?

Each tool has its own version management, PATH handling, and update process. Switching between projects is a hassle, and upgrading means running commands one by one. mise (formerly rtx, written in Rust) is the most powerful cross-language version manager, capable of managing Node, Bun, Rust, Go, uv (even Deno, Python, Terraform, etc.), with fast performance, clean shims, and flexible global/project-level configuration.

My Actual Versions (March 21, 2026)

After cleaning up old tools, install everything with one command mise use --global ...@latest:

  • Node.js: v25.8.1 (Current channel latest, LTS is v24.14.0)
  • Bun: 1.3.11 (latest)
  • uv: 0.10.12 (via aqua backend)
  • Rust: 1.94.0 (stable, released 2026-03-02)
  • Go: 1.26.1 (latest patch)

These versions are queried in real-time from official sources. Using @latest pulls Current; for LTS use node@lts or node@24.

Why Choose mise Over asdf / proto / Manual Scripts?

ToolOne-command upgrade all?Supports uv/Bun/Rust/Node/Go?Unified config?Speed / Community
miseYes (mise upgrade --bump)Native + aqua full coverageYes (.mise.toml)★★★★★
asdfPartial (multi-step)Via pluginsYes (.tool-versions)★★★☆☆
protoPartialLess matureYes★★★☆☆
ManualCustomDepends on youNo★★☆☆☆

mise wins: written in Rust for speed, real shims (not symlinks), built-in core backends, aqua registry for new tools like uv, and task running (like Makefile).

Step 1: Clean Up Old Tools Completely (Avoid Conflicts)

Warning: Back up important global packages (like ~/.cargo/bin tools, global node_modules, etc.) before proceeding.

1. Uninstall fnm + Node

rm -rf ~/.fnm ~/.local/share/fnm
# Edit ~/.zshrc / ~/.bashrc, remove fnm lines (e.g., eval "$(fnm env --use-on-cd)")
# Remove residual binaries
rm -f ~/.local/bin/node ~/.local/bin/npm ~/.local/bin/npx /usr/local/bin/node*

2. Uninstall rustup

rustup self uninstall

3. Uninstall Manually Installed Go

# Find and remove Go installation directory
rm -rf /usr/local/go ~/.go
# Edit PATH, remove /usr/local/go/bin

4. Uninstall curl-installed uv/Bun

rm -f ~/.local/bin/uv ~/.local/bin/bun ~/.cargo/bin/uv ~/.cargo/bin/bun

Step 2: Install mise

macOS / Linux One-liner

# Universal (auto-detects shell)
curl https://mise.run | sh

The universal install puts mise at ~/.local/bin/mise, then manually add activation:

echo 'eval "$(mise activate zsh)"' >> ~/.zshrc
source ~/.zshrc
# Or choose by shell (auto-configures activation)
zsh curl https://mise.run/zsh | sh
bash curl https://mise.run/bash | sh
fish curl https://mise.run/fish | sh

# Or via Homebrew
brew install mise

When using shell-specific commands, the installer automatically adds activation to the corresponding config:

  • zsh~/.zshrc
  • bash~/.bashrc
  • fish~/.config/fish/config.fish

Verify Installation

mise doctor

Step 3: Configure Global Tools (@latest)

Create or edit ~/.config/mise/config.toml:

[tools]
node = "latest"
bun = "latest"
uv = "latest"
rust = "latest"
go = "latest"

Or one-liner:

mise use --global node@latest bun@latest uv@latest rust@latest go@latest

Step 4: Project-level Auto-switching (.mise.toml)

Place .mise.toml in your project root:

[tools]
node = "20"
python = "3.12"

Now entering the project directory automatically switches versions; leaving reverts to global.

Quick Command Reference

mise list              # List installed tools and versions
mise upgrade           # Upgrade all tools to latest
mise upgrade --bump    # Upgrade all and update version numbers in config
mise run <task>        # Run Task defined in .mise.toml
mise settings          # View/modify mise settings
mise doctor            # Check mise status and potential issues

mise Backends: core vs aqua

  • core: Built-in support for Node.js, Rust, Go, Python, Ruby, Deno, and more.
  • aqua: Via aqua-installer plugin, supports uv, Bun, Buf, Cargo, and other emerging tools.

For tools not in core, use aqua:

mise use --global uv@latest   # Default uses core
# Or force aqua
MISE_AQUA_VERSION_RESOLVER=latest mise use -g uv@latest

FAQ

A: mise places shims (stubs) ahead in $PATH that directly invoke real executables, keeping $HOME clean (no .node-version etc.). asdf uses symlinks which can cause conflicts.

Q: Works with direnv?

A: Perfect combo. .mise.toml triggers direnv automatically; use mise direnv to generate .envrc:

mise direnv export bash >> ~/.config/direnv/direnvrc

Q: How fast?

A: Written in Rust, switches instantly. Actual test: mise use node@20 takes ~0.5s (including download and extraction).

Summary

With mise:

  • ✅ One command to upgrade all tools
  • ✅ One config file for global + project-level versions
  • ✅ Clean PATH after removing old tools
  • ✅ Blazing fast, reliable shims
  • ✅ Supports emerging tools like uv and Bun

Migrating from fnm/rustup/manual scripts to mise is one of the fastest DevOps efficiency gains in 2026.


Related Reading: