Replace nvm, pyenv, and rbenv with mise: One Tool for All Your Runtime Versions
Install mise once, pin Node, Python, and Ruby in a single config file, and let every teammate get the same toolchain on clone.
What you'll build
By the end, you'll have mise installed, your shell configured to auto-switch runtimes, and a mise.toml file committing Node 20, Python 3.12, and Ruby 3.3 to a project. Any teammate who clones it and runs mise install gets those exact versions.
Prerequisites
- macOS 12+ or Linux (Ubuntu 20.04+). Windows users: use WSL2.
- Git 2.x installed and on your PATH.
- Homebrew if you're on macOS (
brew --versionto confirm). - If nvm, pyenv, or rbenv are installed, disable their shell hooks in your
.bashrc/.zshrcbefore proceeding. Their hooks load last and override mise when still active.
1. Install mise
macOS:
brew install mise
Linux:
curl https://mise.run | sh
The Linux script installs to ~/.local/bin/mise without requiring sudo. Confirm it worked using the full path, since ~/.local/bin is not in your active shell's PATH yet:
~/.local/bin/mise --version
On macOS via Homebrew, mise --version works immediately.
2. Activate the shell hook
mise needs a hook in your shell config to auto-switch versions when you change directories.
zsh (default on macOS Ventura and later):
echo 'eval "$(mise activate zsh)"' >> ~/.zshrc && source ~/.zshrc
bash (default on most Linux). Use the absolute path so the hook works before ~/.local/bin is on PATH:
echo 'eval "$(~/.local/bin/mise activate bash)"' >> ~/.bashrc && source ~/.bashrc
Run mise doctor after reloading your shell. No errors means the hook is set up correctly.
3. Create a project
mkdir -p ~/my-project && cd ~/my-project && git init
The git init is here on purpose. You'll commit mise.toml in Step 5, and that commit is what lets teammates pick up the same runtimes on clone.
4. Pin your runtimes
Run this from inside the project directory:
mise use node@20.11.0 python@3.12.2 ruby@3.3.0
This installs all three runtimes and writes a mise.toml to the project root. Node and Python both install quickly using precompiled binaries. Ruby compiles from source, so that one takes a few minutes on the first run. After that, mise caches installed versions in ~/.local/share/mise/installs/ and reuses them across projects.
5. Commit the file
git add mise.toml
git commit -m "Pin runtimes via mise"
That's the whole workflow. A collaborator clones the repo, runs mise install once, and has the right toolchain. No README footnotes, no per-machine setup dance.
Verify it works
From inside ~/my-project, check what mise has active and which file set each version:
mise ls --current
Expected output:
node 20.11.0 ~/my-project/mise.toml
python 3.12.2 ~/my-project/mise.toml
ruby 3.3.0 ~/my-project/mise.toml
Now cd out of the project and run mise ls --current again. Those versions disappear or fall back to your global config. That automatic switch is the shell hook from Step 2.
Troubleshooting
mise: command not found on Linux
The installer puts mise in ~/.local/bin, but that directory may not be in your PATH automatically. Add this to your .bashrc or .zshrc, then re-source it:
export PATH="$HOME/.local/bin:$PATH"
Ruby build fails on Linux Ruby compiles from source and needs system libraries. Missing headers cause cryptic failures mid-build. Install the full set first:
sudo apt-get install -y build-essential libssl-dev zlib1g-dev libreadline-dev libyaml-dev libffi-dev libsqlite3-dev liblzma-dev
Then re-run mise use ruby@3.3.0.
Old version managers still winning
If nvm, pyenv, or rbenv are still loading in your shell config, their hooks override mise. Search your .zshrc or .bashrc for nvm, pyenv init, and rbenv init lines, comment them out, then re-source the file.
git commit fails with "Author identity unknown"
This is a fresh git repo on a machine without global git config. Set it once:
git config --global user.email "you@example.com"
git config --global user.name "Your Name"
Next steps
- More tools: mise covers Go, Java, Terraform, and many others. See the full registry at https://mise.jdx.dev.
- Global defaults:
mise use --global node@20.11.0writes a fallback version to~/.config/mise/config.toml, active anywhere no project file is found. - CI: The official
jdx/mise-actionfor GitHub Actions installs mise and your pinned versions in a single step. - Full CLI reference: https://mise.jdx.dev/cli/
Mariana covers the fast-moving world of machine learning and generative AI, with a particular focus on how these technologies are reshaping development workflows. When she isn't stress-testing the latest foundation models, she's usually at a local hackathon.
Discussion 0
No comments yet
Be the first to weigh in.