Migrating from asdf to mise: Keep Your .tool-versions (with Command Mapping)
Developers are steadily moving from asdf — the long-standing standard for managing Node.js, Python, and Ruby versions — to mise (mise-en-place). mise reads asdf's .tool-versions files as-is, while folding environment variable management (a direnv replacement) and a task runner into a single tool.
This guide walks through the migration in order: install → switch shell activation → bulk-install your tools → retire asdf. The command mapping tables are built by cross-checking our verified reference data for the asdf command reference (23 commands) and the mise command reference (60 commands).
When you need detailed descriptions, options, and examples for individual commands, keep both reference pages open alongside this article. Everything here reflects Go-based asdf (v0.16+) / mise v2026.x (as of July 2026).
1. Why People Are Migrating from asdf to mise
The biggest trigger is asdf's own generational shift. In early 2025, asdf v0.16 was fully rewritten from Bash to Go — dramatically faster, but with breaking changes such as asdf global / asdf local being consolidated into asdf set. Since you have to relearn commands anyway, many users take this opportunity to evaluate mise instead.
What mise brings to the table boils down to three things:
- Compatibility with your asdf assets: it reads
.tool-versionsdirectly and can use asdf plugins, so migration involves almost no rewriting - Fast, shim-less operation: the
reshimritual asdf was famous for is essentially gone, andwhich nodepoints at the real binary - One tool, three jobs: version management plus environment variables (a direnv replacement) plus a task runner, all in one
mise.toml
2. What Is mise — Four Things asdf Users Should Know
mise is a dev tool manager written in Rust. From an asdf user's perspective:
.tool-versionscompatible: existing files in your repositories are recognized without conversion. Teammates who stay on asdf can coexist in the same repo- No plugins needed for core tools: Node.js, Python, Ruby, Go, and other major tools are built into the registry (900+ tools) —
mise use node@22is all it takes. The whole "add a plugin first" step disappears - Shim-less by default: mise manipulates PATH directly, so
reshimis unnecessary. If you need shims for IDE integration,mise activate zsh --shimskeeps the traditional behavior - Niche tools fall back to asdf plugins: for tools missing from the registry, point at an asdf plugin's Git URL —
mise plugins install custom https://github.com/user/asdf-custom.git
3. Migration Steps (4 Steps)
Step 1: Install mise
# macOS / Linux (Homebrew)
brew install mise
# Installer script
curl https://mise.run | sh
Step 2: Switch Shell Activation
In .zshrc (or .bashrc), remove the asdf initialization line and add mise's one-liner.
# Remove: asdf initialization (example)
# export PATH="${ASDF_DATA_DIR:-$HOME/.asdf}/shims:$PATH"
# Add: mise shell integration
eval "$(mise activate zsh)"
Do not activate asdf and mise at the same time. With both manipulating PATH and shims, which version wins becomes unpredictable. Restart your shell after switching.
Step 3: Bulk-Install Your Tools
In your project directory (or wherever .tool-versions lives):
mise install
mise install installs every tool defined in .tool-versions and mise.toml. Note that versions already installed under asdf are installed again into mise's own directory (~/.local/share/mise/) — mise does not reuse asdf's installations.
Coming from nvm, pyenv, or rbenv? Dedicated sync commands can pick up your existing installations:
mise sync node --nvm # make nvm's Node.js versions available to mise
mise sync python # sync Python versions from pyenv
mise sync ruby # sync Ruby versions from rbenv
Step 4: Verify, Then Retire asdf
mise doctor # diagnose environment issues
mise ls --current # confirm which tools/versions are active
node --version # confirm the tools actually run
Once everything checks out, remove asdf (brew uninstall asdf for Homebrew installs, then delete ~/.asdf). Only delete after verifying everything works under mise.
4. Command Mapping (asdf → mise)
The tables are based on the commands covered by both references.
Tool Management
| Goal | asdf | mise | Notes |
|---|---|---|---|
| Set a version | asdf set <tool> <ver> |
mise use <tool>@<ver> |
mise also installs and records it in mise.toml; use mise use --global for global config |
| Install only | asdf install <tool> <ver> |
mise install <tool>@<ver> |
Leaves config files untouched |
| Install everything defined | asdf install |
mise install |
Both work with no arguments |
| Uninstall | asdf uninstall |
mise uninstall |
|
| Show current versions | asdf current |
mise ls --current (-c) |
|
| List installed versions | asdf list |
mise ls |
|
| List all available versions | asdf list all <tool> |
mise ls-remote <tool> |
|
| Show latest stable | asdf latest |
mise latest |
Same name |
Plugin Management
| Goal | asdf | mise | Notes |
|---|---|---|---|
| Add a plugin | asdf plugin add |
mise plugins install |
Unnecessary for core tools in mise (built-in registry); accepts asdf plugin Git URLs |
| List installed plugins | asdf plugin list |
mise plugins ls |
|
| List all available plugins | asdf plugin list all |
mise plugins ls-remote / mise registry |
mise search queries the registry too |
| Remove a plugin | asdf plugin remove |
mise plugins uninstall |
|
| Update plugins | asdf plugin update / --all |
mise plugins update |
Utilities
| Goal | asdf | mise | Notes |
|---|---|---|---|
| Show install path | asdf where |
mise where |
Same name |
| Show executable path | asdf which |
mise which |
Shim-less mise points at the real binary |
| Run a command with a specific version | asdf exec |
mise exec |
|
| Regenerate shims | asdf reshim |
mise reshim |
Rarely needed in mise (only with --shims activation) |
| Show version | asdf version |
mise version |
|
| Shell completions | asdf completion |
mise completion |
|
| Environment diagnosis | asdf info (info dump) |
mise doctor |
mise goes further and diagnoses problems |
mise Features with No asdf Counterpart
Commands you gain after migrating:
| Command | What it does |
|---|---|
mise upgrade / mise outdated |
Bulk-upgrade tools and list what's outdated |
mise prune |
Clean up unused versions |
mise run / mise tasks ls |
Run and list tasks defined in mise.toml (task runner) |
mise set / mise env |
Set and export environment variables (direnv replacement) |
mise sync node / python / ruby |
Import installations from nvm, pyenv, rbenv |
mise self-update |
Update mise itself |
5. .tool-versions vs mise.toml
Right after migrating, staying on .tool-versions is perfectly fine. Since mise reads it without conversion, you can switch to mise personally without touching your team's repository files.
To use mise at full power, consider moving to mise.toml, which unifies environment variables and tasks:
[tools]
node = "22"
python = "3.12"
[env]
DATABASE_URL = "postgres://localhost/mydb"
[tasks.test]
run = "npm test"
Running mise use node@22 appends to mise.toml automatically, so you rarely write it by hand. Environment variables can be added with mise set DATABASE_URL=..., and tasks with mise tasks add.
6. Gotchas
- Double activation of asdf and mise: the most common accident. If both initialization lines remain in
.zshrc, PATH resolution becomes unpredictable. Always remove the asdf line when switching - Shim-dependent environments: JetBrains IDEs and some CI configs reference shim paths directly, which no longer exist under shim-less mise. Either switch to shim mode with
mise activate zsh --shims, or update the config with the real path frommise which <tool> asdf envandmise envare different beasts: asdf'senvruns a utility inside the shim execution environment, while mise'senvexports environment variables in shell format. Same name, different jobs- Installations are not carried over: mise installs tools into its own
~/.local/share/mise/. The firstmise installdownloads everything, so run it on a good network (from nvm/pyenv/rbenv you can reuse existing installs viamise sync) - Coming from Bash-based asdf (v0.15 and earlier):
asdf global/asdf localwere already consolidated intoasdf setin the Go rewrite. In mise, their successors aremise use --global/mise userespectively
FAQ
Can I keep using .tool-versions?
Yes. mise reads .tool-versions without conversion, so you can coexist in the same repository with teammates who still use asdf. Moving to mise.toml is optional.
Can I use my asdf plugins?
Core tools (Node.js, Python, Ruby, Go, and so on) are built into the registry, so no plugin is needed at all. For niche tools missing from the registry, run mise plugins install <name> <git-repo-url> pointing at the asdf plugin.
Can asdf and mise coexist?
Activating both shell integrations is discouraged — which tool wins depends on PATH order. During a transition period, keep only mise activated and call the old environment explicitly with asdf exec when needed.
Is reshim really gone?
With the default activation (direct PATH manipulation), yes. Only if you opt into shim mode with --shims does mise reshim come back into play, just like asdf.
Does mise replace direnv?
For most cases, yes. Per-directory environment variables live in the [env] section of mise.toml (or are set via mise set).
When is it safe to delete asdf?
After mise doctor and mise ls --current look clean and your key tools actually run. Deleting ~/.asdf removes all of asdf's installed versions.
Summary
- mise is
.tool-versions-compatible, so the actual migration is just two moves: switch shell activation + runmise install - Most commands migrate by the same name (
install/where/which/latest). The big changes:asdf set→mise use(which also installs), and plugin management mostly disappears - Shim-less operation frees you from
reshim— but rescue shim-dependent IDE/CI setups with--shims - After migrating, you gain environment variable management (direnv replacement) and a task runner in a single
mise.toml
For the full command list with detailed descriptions and examples, see our maintained, data-verified references:
- mise command reference — all 60 commands across tools, tasks, env vars, and config
- asdf command reference — all 23 commands of Go-based asdf