Skip to content

mise/asdf — Universal Version Manager for Developer Tools

DodaTech Updated 2026-06-24 8 min read

In this tutorial, you'll learn about mise/asdf. We cover key concepts, practical examples, and best practices to help you understand and apply this topic effectively.

mise (formerly rtx) and asdf are universal version managers that install and switch between multiple versions of programming languages and tools — Node.js, Python, Rust, Go, Java, Terraform — using a single .tool-versions file per project.

What You'll Learn

How to use mise and asdf to install and manage runtime versions, pin project-specific versions with .tool-versions, migrate from nvm, pyenv, and gvm to a single tool, configure automatic version switching in your shell, and use mise's faster Rust-based implementation.

Why a Universal Version Manager Matters

Developers juggle multiple projects that require different versions of the same tool — Node.js 18 for one project, Node.js 20 for another. Traditional version managers (nvm, pyenv, rbenv) are language-specific, slow, and use different interfaces. asdf provides a single interface with a plugin system for 500+ tools. mise is a faster, Rust-based reimplementation of asdf with additional features like task running and environment variable management. DodaZIP's Monorepo uses a .tool-versions file checked into Git, ensuring every developer and CI runner uses identical tool versions.

Learning Path

flowchart LR
  A[Starship Prompt] --> B[mise/asdf
You are here] B --> C[hyperfine] B --> D[Zsh & Oh My Zsh] style B fill:#f90,color:#fff

asdf — The Original Universal Version Manager

Installation

# Clone asdf
git clone https://github.com/asdf-vm/asdf.git ~/.asdf --branch v0.14.0

# Add to shell
echo '. "$HOME/.asdf/asdf.sh"' >> ~/.zshrc
echo '. "$HOME/.asdf/completions/asdf.bash"' >> ~/.zshrc
source ~/.zshrc

Installing Plugins and Tools

# Install a plugin
asdf plugin add nodejs
asdf plugin add python
asdf plugin add rust
asdf plugin add golang
asdf plugin add terraform

# List all plugins
asdf plugin list all | grep -E "node|python|rust"

# Install a specific version
asdf install nodejs 20.12.0
asdf install python 3.12.0
asdf install rust 1.78.0

# List installed versions
asdf list nodejs
asdf list python

Version Management

# Set global default
asdf global nodejs 20.12.0
asdf global python 3.12.0

# Set local (project-specific) version
cd /my/project
asdf local nodejs 18.19.0
asdf local python 3.11.0

# This creates a .tool-versions file:
cat .tool-versions
# nodejs 18.19.0
# python 3.11.0

# Use a version for current shell only
asdf shell nodejs 16.20.0

# Show current version
node --version
python --version

.tool-versions File

The .tool-versions file is central to asdf's workflow:

# Place this file in the root of your project
# .tool-versions
nodejs 20.12.0
python 3.12.0
rust 1.78.0
golang 1.22.0
terraform 1.7.0

# Multiple versions (e.g., for testing)
nodejs 18.19.0 20.12.0

# Comment lines are supported
# Use specific version for CI

Plugin Management

# Update all plugins
asdf plugin update --all

# Update a specific plugin
asdf plugin update nodejs

# Remove a plugin
asdf plugin remove python

# List all installed plugins with URLs
asdf plugin list --urls

# Add a plugin from a custom source
asdf plugin add myplugin https://github.com/user/asdf-myplugin.git

mise — The Faster Successor

mise (formerly rtx) is a Rust reimplementation of asdf that is 10-100x faster, supports .tool-versions and .mise.toml configs, and adds task running and environment variable management.

Installation

# macOS
brew install mise

# Linux/macOS (curl)
curl https://mise.jdx.dev/install.sh | sh

# Or from source
cargo install mise

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

Basic Usage

# List available versions
mise ls-remote nodejs
mise ls-remote python@3.12

# Install a version
mise install nodejs@20.12.0

# Set versions
mise use --global nodejs@20.12.0
mise use nodejs@18.19.0    # Creates .tool-versions in current dir
mise use python@3.12.0

# List installed
mise ls

# Current version
mise current nodejs
node --version

mise Configuration Formats

mise supports ~/.config/mise/config.toml for global config and mise.toml or .tool-versions for project config:

# ~/.config/mise/config.toml
[env]
EDITOR = "vim"
NODE_ENV = "development"

[tools]
nodejs = "20.12.0"
python = "3.12.0"
rust = "1.78.0"
golang = "1.22.0"
terraform = "1.7.0"

[plugins]
nodejs = "https://github.com/asdf-vm/asdf-nodejs"
# mise.toml (project-specific)
[tools]
nodejs = "18.19.0"
python = "3.11.0"

[env]
DATABASE_URL = "postgres://localhost:5432/myapp"

Task Runner

mise includes a built-in task runner:

# mise.toml
[tasks.lint]
run = "eslint ."
depends = ["install"]

[tasks.test]
run = "jest"
depends = ["lint"]

[tasks.build]
run = "npm run build"
depends = ["test"]

[tasks.install]
run = "npm install"

[tasks.dev]
run = "npm run dev"
depends = ["install"]
mise run lint
mise run test
mise run build

Environment Variables

# mise.toml
[env]
DATABASE_URL = "postgres://localhost:5432/myapp"
AWS_REGION = "us-east-1"
NODE_ENV = { if = "test", value = "test" }
NODE_ENV = { if = "production", value = "production" }
mise env  # Shows all environment variables mise would set

Migrating from asdf to mise

# mise is backward-compatible with .tool-versions
# Simply install mise and activate it
# It reads existing .tool-versions and asdf plugins

# Migrate asdf plugins and tools
mise plugins install nodejs
mise install nodejs@20.12.0

# Copy .tool-versions — mise reads them natively
cp .tool-versions mise.toml  # Optional: upgrade to TOML format

Migration from nvm/pyenv/rbenv

# From nvm, switch to asdf/mise:
nvm ls                # List installed Node versions
asdf install nodejs $(nvm ls | tail -1)  # Install the version you need
asdf global nodejs <version>
npm install -g yarn   # Global packages work with asdf-shim

# From pyenv:
pyenv versions
asdf install python $(pyenv version | cut -d' ' -f1)
asdf global python <version>

# Clean up old version managers
brew uninstall nvm pyenv rbenv
rm -rf ~/.nvm ~/.pyenv ~/.rbenv

Working with Global Packages

# npm global packages work across versions
npm install -g yarn pnpm typescript

# Python packages with pip
pip install pytest black mypy

# Each version has its own gem/pip/npm directory
# Switching versions switches the global packages too

Performance Comparison

# asdf vs mise speed comparison
time asdf current
time mise current

# mise is typically 10-50x faster because it's written in Rust
# and does not use a shim-based approach for all commands

Common Errors

1. "command not found: node" After asdf Install

The shim directory is not in PATH. Ensure $ASDF_DIR/shims is in PATH. With the standard setup script, this happens automatically. Run asdf reshim nodejs.

2. asdf Install Stalls or Fails

Some plugins (especially Node.js and Python) compile from source or download large archives. Check disk space, network, and available build tools (build-essential, gcc, make).

3. mise Activate Not Working

Ensure eval "$(mise activate zsh)" is the last eval statement in your shell config. It must come after any other version manager configurations.

4. .tool-versions in Wrong Directory

asdf and mise search upward from the current directory for .tool-versions or mise.toml. If the file is too far up (outside the project boundary), it may not be found.

5. Plugin Not Found for a Tool

Not every tool has an asdf plugin. Check the plugins Repository at github.com/asdf-vm/asdf-plugins or search on GitHub for asdf-<toolname>.

6. Global Packages Not Available After Version Switch

Each asdf version has its own gem/pip/npm directory. After switching, reinstall global packages or use mise's env section to set PATH entries.

7. asdf Reshim Required After Global Package Install

After npm install -g, the new binaries are not automatically shimmed. Run asdf reshim nodejs to create shims for global packages.

Practice Questions

1. What file does asdf use to pin project-specific tool versions? .tool-versions — placed in the project root, listing tool name and version per line.

2. How is mise different from asdf? mise is a Rust-based reimplementation of asdf that is faster, adds TOML config format, built-in task runner, and environment variable management.

3. How do you set a global default Node.js version with asdf? asdf global nodejs 20.12.0 — sets the version used outside of project-specific directories.

4. How do you install a plugin in asdf? asdf plugin add nodejs — downloads and installs the plugin from the asdf plugins Repository.

5. What command creates a .tool-versions file in the current directory using mise? mise use nodejs@20.12.0 — sets the version and creates .tool-versions (or mise.toml).

Challenge: Migrate your development environment from nvm/pyenv/gvm to mise. Install the exact versions of Node.js, Python, Rust, and Go that your current projects need. Create a .tool-versions file that matches each project's requirements. Set up mise to automatically switch versions when you cd into each project. Verify by checking that node --version, python --version, rustc --version, and go version all match the expected project versions.

Do I need to uninstall nvm before using asdf?

No — but having both active can cause conflicts. Deactivate nvm (unalias nvm, remove from shell config) before using asdf.

Can I use asdf plugins with mise?

Yes — mise is backward-compatible with asdf plugins. They work without modification.

Does asdf work on Windows?

asdf works via WSL (Windows Subsystem for Linux). Native Windows support is limited.

How do I uninstall a specific version?

asdf uninstall nodejs 18.19.0 removes the version's installation directory.

What happens if different projects require different versions?

asdf and mise switch versions automatically based on the .tool-versions file in the project directory when you cd into it. No manual switches needed.

What's Next

hyperfine — CLI Benchmarking Guide
Zsh & Oh My Zsh — Shell Enhancement
Starship Prompt — Custom Shell Prompt

Built by the developers of Doda Browser, DodaZIP, and Durga Antivirus Pro. Updated 2026-06-24.

Built by the developers of DodaTech

Doda Browser, DodaZIP & Durga Antivirus Pro