I normally use Arch’s package management to install new languages and environments. The package manager is mostly up-to-date and easy to use.
If you run a system-wide update, it also installs new versions of a package.

The Problem

Some repositories on my machine use older versions of Node or Elixir.
When I run those applications, I might get errors.

Sometimes Arch packages don’t use the latest version. For example, the Elixir installation uses version 1.9.2-1. The latest version is 1.9.4.

On the other hand, some plugins don’t work well with the lastest installation. Merlin, the code helper for OCaml, needs OCaml version 4.08.1. Arch installs 4.09.1.

Enter asdf

With a version manager, you can fine-tune your language version. Several languages offer tools for such a use-case. Node has nvm, Python has pyenv, Ruby has RVM.

But it’s a hassle to use several different tools for every language that I use.

asdf to the rescue!

Manage multiple runtime versions with a single CLI tool, extendable via plugins


Finally a tool that has decent installation instructions.

Here’s how you’ll do it with git (you can also use Homebrew on MacOs):

git clone https://github.com/asdf-vm/asdf.git ~/.asdf
cd ~/.asdf
git checkout "$(git describe --abbrev=0 --tags)"

Then you have to add asdf to your shell.

Here’s bash:

echo -e '\n. $HOME/.asdf/asdf.sh' >> ~/.bashrc
echo -e '\n. $HOME/.asdf/completions/asdf.bash' >> ~/.bashrc

Here’s fish:

echo 'source ~/.asdf/asdf.fish' >> ~/.config/fish/config.fish
mkdir -p ~/.config/fish/completions; and cp ~/.asdf/completions/asdf.fish ~/.config/fish/completions

Plugin Management

asdf uses the concept of plugins for installing different languages.

See asdf plugin-list-all | less to get an overview.

You can add a package with the command asdf plugin-add <package>.

Here’s an example:

asdf plugin-add python

This doesn’t install a language package. First, find the version you want to install.

asdf list-all python

Then, install the version you need:

asdf install python 3.6.2

You can install as many versions as you like.

Define the global version:

asdf global python 3.6.2

You can also define local versions of a package. Go to the project folder, and use asdf local <language/package name> <version>.

Ugly Parts

The tool doesn’t work on its own. asdf requires several dependencies that have to be installed on your machine.
An up-do-date Arch system has you covered, though.

Erlang needs you to set environment variables to build the installation.

You also have to make sure that Erlang and Elixir play well. First, install an OTP Erlang version with asdf. Then you have to find a compatible pre-compiled version for Elixir.

Some plugins are in need of a maintainer, for example, Nim. For those niche languages, I’m not confident that asdf is the right solution.

In the end, you still have to use a language-specific version manager for some languages. And now you’re back to square one, as you maintain several tools for different languages.

Nice Parts

For those languages that do work, asdf offers a one-size-fits-all solution. The documentation is exhaustive and supports both MacOS and Linux, as well as different shells (bash, zsh, fish).


One alternative is Nix, the “purely functional package manager”.
I found the documentation confusing. Using it with fish shell doesn’t work out of the box.
I’m still unsure about how to install packages. Does it create a different package and environment for each project?

Now what?

asdf offers a decent replacement for language-specific version managers.
The documentation surprised me with a good structure and by covering many topics. asdf offers a unified experience and alternative to using myriad other language versioning packages - as long as the asdf community supports the desired languages.

Further Reading