← All articles
Computer code on a dark screen with line numbers.

mise: Modern Dev Tools Version Manager

Developer Tools 2026-03-04 · 4 min read mise version manager node.js python asdf nvm alternative developer tools shell devtools
By DevTools Guide Editorial TeamSoftware engineers and developer advocates covering tools, workflows, and productivity for modern development teams.

Most developers manage multiple version managers: nvm for Node.js, pyenv for Python, rbenv for Ruby, goenv for Go. Each has separate config files, hooks, and commands. mise (pronounced "meeze", previously rtx) replaces all of them. It's a single Rust-based tool that installs and manages runtime versions for any language, reads .tool-versions files for project consistency, and runs 3-10x faster than asdf (which it's API-compatible with).

Photo by Harshit Katiyar on Unsplash

Why mise

Single tool for all runtimes: Install Node 20, Python 3.12, Ruby 3.3, and Go 1.22 with one tool and one config file.

Speed: Written in Rust. Activating mise adds ~2ms to shell startup vs 50-100ms for asdf. Installing tools is parallelized.

asdf compatibility: mise reads .tool-versions files (asdf's format). Switch from asdf to mise with no project file changes.

Project-scoped versions: Put a .mise.toml or .tool-versions in your project directory — anyone who clones the repo gets the same tool versions.

Task runner: mise includes a task runner that reads from .mise.toml, eliminating the need for Makefiles for simple project tasks.

Installation

# macOS (Homebrew)
brew install mise

# Linux/macOS (curl installer)
curl https://mise.run | sh

# Cargo
cargo install mise

Add to shell profile:

# bash
echo 'eval "$(mise activate bash)"' >> ~/.bashrc

# zsh
echo 'eval "$(mise activate zsh)"' >> ~/.zshrc

# fish
echo 'mise activate fish | source' >> ~/.config/fish/config.fish

Basic Usage

# Install a specific version
mise install node@20
mise install node@lts
mise install [email protected]
mise install [email protected]
mise install [email protected]

# Set global defaults
mise use --global node@20
mise use --global [email protected]

# Set project-scoped versions (writes to .mise.toml)
cd my-project
mise use node@18
mise use [email protected]

# Check current versions
mise current

# List installed versions
mise list

# Update all tools
mise upgrade

Like what you're reading? Subscribe to DevTools Guide — free weekly guides in your inbox.

.mise.toml — Project Configuration

mise uses .mise.toml for project configuration:

# .mise.toml
[tools]
node = "20"
python = "3.12"
ruby = "3.3"
go = "1.22"

# Install a specific minor version
terraform = "1.7.0"

# Multiple versions (primary + alternates)
node = ["20", "18"]

[env]
# Environment variables when in this project
DATABASE_URL = "postgres://localhost/myapp_dev"
NODE_ENV = "development"

[tasks.test]
description = "Run tests"
run = "npm test"

[tasks.build]
description = "Build the project"
run = "npm run build"

[tasks.dev]
description = "Start dev server"
run = "npm run dev"

.tool-versions Compatibility

If you're coming from asdf:

# .tool-versions (asdf format — mise reads this too)
nodejs 20.10.0
python 3.12.0
ruby 3.3.0

mise reads both .mise.toml and .tool-versions — no migration required.

Installing Tools (Plugins)

mise uses the same plugin ecosystem as asdf. Most tools are available by default:

# List available tools
mise plugins ls-remote

# Install from the registry
mise install [email protected]
mise install [email protected]
mise install [email protected]
mise install awscli@2
mise install rust@stable

# Install a tool using a URL-based plugin
mise plugin install my-tool https://github.com/org/asdf-my-tool

Task Runner

mise includes a built-in task runner:

# .mise.toml
[tasks.test]
description = "Run the test suite"
run = "pytest tests/ -v"
depends = ["install"]

[tasks.install]
description = "Install dependencies"
run = "pip install -r requirements.txt"

[tasks.lint]
description = "Run linters"
run = [
  "flake8 src/",
  "mypy src/",
]

[tasks.ci]
description = "Full CI pipeline"
depends = ["install", "lint", "test"]
mise run test
mise run lint
mise run ci
mise tasks  # List all tasks

Shell Integration

mise automatically activates the correct versions when you cd into a project:

cd ~/projects/new-app       # Uses .mise.toml: node@20
cd ~/projects/legacy-app    # Uses .tool-versions: node@14

No manual nvm use or pyenv local needed. mise hooks into your shell's cd command.

Environment Variables

mise can manage per-project environment variables:

[env]
DATABASE_URL = "postgres://localhost/dev"
SECRET_KEY = "dev-secret-key"

Or reference external files (with .mise.toml in .gitignore):

[env]
_.file = ".env"

This replaces direnv for many use cases.

Migration from nvm / pyenv / asdf

From nvm:

# Install mise
curl https://mise.run | sh
# Add to shell profile
echo 'eval "$(mise activate zsh)"' >> ~/.zshrc

# Set global node version
mise use --global node@20

# Remove nvm from shell profile
# Remove ~/.nvm and nvm shell hooks

From asdf: Nothing to change — mise reads your .tool-versions files.

mise vs asdf

mise asdf
Language Rust Bash
Shell activation ~2ms ~50-100ms
Parallel installs
.tool-versions compat ✓ (native)
.mise.toml
Task runner
Env variables Via plugin
Plugin ecosystem Same as asdf Native

mise vs nvm

nvm is Node.js specific. mise handles Node, Python, Ruby, Go, and 300+ other tools. If you only use Node, nvm works. For polyglot development, mise handles everything.

Shell Prompt Integration

Show active tool versions in your prompt (works with Starship):

# ~/.config/starship.toml
[mise]
format = "[$symbol$version]($style) "
symbol = "mise "

Or use mise current in your prompt script to show active versions.

mise is a substantial quality-of-life improvement for developers working with multiple runtimes and projects. The asdf compatibility makes migration nearly effortless.

Get free weekly tips in your inbox. Subscribe to DevTools Guide