From asdf to mise
Runtime version managers like asdf let you install, manage, and switch between multiple runtime versions of tools in isolated environments. They help get consistent development setups across projects.
I used asdf over the past couple of years to manage and install multiple versions of kubectl and various developer tools. In 2025, asdf 0.16 was rewritten in Go; before, it was written in Bash. The upgrade process wasn’t completely straightforward, so I took this opportunity to look for alternatives.
I found mise, aka “mise-en-place,” formerly rtx. After comparing asdf to mise, I decided to give it a try, and I am glad I did. The migration from asdf was quick and easy. Mise has several advantages over asdf.
Better UI🔗
After 2 years of using asdf, I still found it difficult to remember its commands. I had to regularly look at the help and documentation. For example, to use the latest version of golang by default:
$ asdf plugin add go
$ asdf install go latest
$ asdf global go latest
With mise, you simply have to run:
$ mise use -g go@latest
Mise is quick and easy to remember, and most commands are like that.
Better security🔗
Asdf plugins aren’t secure. It’s a bunch of shell scripts written by third parties that run with full permissions in the user’s environment. Mise relies primarily on registries like aqua and ubi. Releases are signed, and there’s no shell script running in the user’s environment.
More packages🔗
Mise can also use asdf plugins as a last resort. So if a package isn’t available on the mise registries, you can still fall back to the asdf plugins. Mise also supports installing binaries directly with Cargo, Pipx, Go, Npm, and more. This flexibility means there are many more tools that can be installed and managed by mise.
Better performance🔗
Mise is quite a bit faster than the shell version of asdf. Its own benchmark shows it’s also faster than the Go rewrite of asdf. I can really feel the difference using it day to day.
Easy to integrate with your shell🔗
To get mise to work with Zsh, I added the following to my zshrc:
if command -v mise > /dev/null
then
eval "$(mise activate zsh)"
eval "$(mise completion zsh)"
fi
I don’t notice any delay when I start Zsh, and because mise generates the scripts when I update it, I don’t have to update my Zsh configuration. There’s also support for Bash and Fish.
Conclusion🔗
When there’s a developer tool that’s missing from my Linux package manager, I can usually install it with mise. It’s been a month since I’ve adopted it, and it’s been fun to use and it’s faster than asdf. I highly recommend you give mise a try if you use multiple developer tools or require tooling that’s not currently packaged for your operating system.