Elixir Version Management (with asdf)
You can install Elixir with a package manager, such as apt
or brew
, but sometimes a developer needs more than a single version installed. This problem isn’t unique to Elixir, so I recommend solving it in a way that isn’t unique to Elixir.
asdf
is the Swiss Army Knife of all version managers, and it has become my version manager of choice for all languages over the past few months. Its author, Akash Manohar — better known as HashNuke — attributes its creation to “high-fever, cold, cough,” and it certainly has the “I just need a tool that actually fits my needs” feel.
Unlike most version managers, asdf
is a framework for managing platforms, and you choose the individual plugins for each platform. This means you choose to use it as much or as little as you want to, but you will need to take a few more minutes in the beginning to set it up. There are official plugins for Elixir and Erlang, as well as Ruby, Python, and Node with more community plugins that go as far as versioning Postgres and Redis. This allows for significant flexibility with multi-language projects.
Note: The instructions below are for macOS with Bash in order to make them accessible to most people. Minimal changes may be needed if you use a Linux distribution or a Bourne-compatible shell besides Bash. Unfortunately, both Windows and other, non-Bourne-compatible shells are outside the scope of this post. Further recommendations are welcome in comments.
You’ll need to install the asdf
tool to begin with. The easiest way is to clone the Git repository and set your shell profile to include the tool:
git clone https://github.com/asdf-vm/asdf.git ~/.asdf --branch 0.1.0
echo '. $HOME/.asdf/asdf.sh' >> ~/.bash_profile
echo '. $HOME/.asdf/completions/asdf.bash' >> ~/.bash_profile
As I mentioned above, asdf
works on a plugin basis. Even once it’s installed, it won’t do anything until you install platform plugins that describe how to build and manage platform versions.
If you already have a compatible version of Erlang installed, you can choose to only install the Elixir plugin. However, I prefer installing both plugins to allow convenient switching between installed versions. This was especially helpful when Erlang 19.0 and Elixir 1.3 were released in the same week. I installed both of the latest releases for testing, but all of my major projects were still pinned against the previous stable versions until my team was ready to upgrade.
Installing a plugin is done using the plugin-add
command followed by the name of the platform and the Git repo URL for the plugin.
asdf plugin-add erlang https://github.com/asdf-vm/asdf-erlang
asdf plugin-add elixir https://github.com/asdf-vm/asdf-elixir
asdf
will download and install the plugins to a local folder. After a plugin is added, you can install any version of the platform the plugin makes available using the install
command. If you need to know which versions you can install, just use the list-all
command. If newer versions you want to install don’t appear in that list, try the plugin-update
command, which pulls down the newest version descriptors.
For example, the commands to install the latest versions of Erlang and Elixir are as follows:
asdf install erlang 19.1
asdf install elixir 1.3.4
During the install process, asdf
will download the appropriate source files locally and perform any compilation necessary. Erlang will take considerably longer to install because it compiles the C code. The majority of Elixir is written in Elixir, so it requires no real compilation phase.
Once installed, the last step to get asdf
to work is to declare the “global” version you wish to use. Whenever a version isn’t declared locally, asdf
will fall back on your global preference.
asdf global erlang 19.1
asdf global elixir 1.3.4
Of course, a version manager is the most useful when you use it to manage versions on a per-project basis, and asdf
shines bright in this area because it can handle version declarations for any number of tools. asdf
uses a unique file called .tool-versions
with a simple format to determine which version of each platform to use. You can use the local
command to create or update the file:
asdf local erlang 18.3
asdf local elixir 1.2.1
This has the added advantage that any collaborate you work with needs to only run asdf install
to get the correct versions of the platform, as long as they have the appropriate plugins installed. This makes it super simple to on-board new team members as well as upgrade to new platform versions.
Other Version Managers for Elixir
I have stuck withasdf
because, quite frankly, I’m tired of trying to find yet another version manager whenever I have to work with a new platform. asdf
works well, and it’s well designed. As a final note, though, I’d like to mention two other version managers available for Elixir that are purely Elixir focused.
For anyone coming to Elixir from a Ruby workflow and experienced with the rbenv
package by Sam Stephenson, exenv
from Yuki Ito will be a natural fit. If you’re looking for a no-frills version manager, kiex
from Taylor Carpenter may be more your style.
I’m sure that as Elixir develops a larger presence worldwide, more version management solutions will come on the scene. I firmly believe, though, that the version management problem shouldn’t be solved on a language-by-language basis when the problem is encountered in every language. asdf
gives a general solution to the problem, which is what I’ve been looking for.