Skip to content
Dev Tools Beginner Tutorial

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.

Mariana Souza
Mariana Souza
Senior Editor · Jun 25, 2026 · 4 min read
Replace nvm, pyenv, and rbenv with mise: One Tool for All Your Runtime Versions

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 --version to confirm).
  • If nvm, pyenv, or rbenv are installed, disable their shell hooks in your .bashrc/.zshrc before 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.0 writes a fallback version to ~/.config/mise/config.toml, active anywhere no project file is found.
  • CI: The official jdx/mise-action for GitHub Actions installs mise and your pinned versions in a single step.
  • Full CLI reference: https://mise.jdx.dev/cli/
Mariana Souza
Written by
Mariana Souza · Senior Editor

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

Join the discussion

Sign in or create an account to comment and vote.

No comments yet

Be the first to weigh in.

Related Reading