Notes to self

Choosing Elixir version manager

Exenv, Kiex or ASDF? What’s the difference?

System version

Before diving into three popular version managers, le’t not forget you can get Elixir from your Linux distribution. On Fedora you can install Elixir with:

$ sudo dnf install elixir

That will install Elixir, including the iex interactive shell and Mix build tool.

System Elixir is usually your easiest and fastest way to get up and running. You can usually install only a single version this way, though.


When I started with Elixir, I used a packaged Fedora version but wanted to have a Vagrant file with the exact project version. That way, I ended up with exenv.

Because I came from the Ruby background and spent some time with rbenv before, adaptation to exenv was straightforward.

The way rbenv and exenv switch version is by using shims executables that you insert into your $PATH. By putting ~/.exenv/shim on your $PATH, the exact Elixir version is detected for you, and the $PATH is further prepended by the requested version from ~/.exenv/versions directory.

exenv offers selecting a global and per-project version (.exenv-version file). You can also provide an environment variable (EXENV_VERSION) or start a shell with the version you want, so it’s very flexible:

$ exenv global 1.10.0
$ exenv local 1.11.0
$ exenv shell 1.11.0

Similar to rbenv, where the build is done with ruby-build installer, the building part is handled by elixir-build.

After you install a new version, you need to rehash the shims:

$ exenv install 1.11.0
$ exenv rehash

elixir-build requires Erlang.


A little bit bare bone variant to exenv is kiex. It’s just a one single file that you source in your shell:

[[ -s "$HOME/.kiex/scripts/kiex" ]] && source "$HOME/.kiex/scripts/kiex"

You cannot go much simpler than that.

To see available version run:

$ kiex list
$ kiex list known

And to select one:

$ kiex use 0.12.5
$ kiex shell 0.12.5
$ kiex default 0.12.5

kiex does not use shims. It just manages the $PATH directly (no need for any rehashing). It doesn’t support per-project switching.

kiex can install the version you want with kiex install command:

$ kiex install 0.12.5

kiex requires Erlang as well.


The last one, but at the same time, the most popular is asdf. ASDF is actually an “extendable version manager” that can let you manage versions or Elixir, Node.js, Ruby, and others within a single user interface with its plugin architecture. But worry not, Elixir is actually among the official upstream plugins.

Similarly to exenv, it uses shims located at ~/.asdf/shims.

Apart from switching several runtimes, you can also use a single .tool-versions config file to define your environment, which is a very cool idea. The downside to this is, that not all plugins are equal. They will let you have a single high-level interface, but the nitty-gritty details and requirements might still differ.

It also supports global or per-shell version:

$ asdf list elixir
$ asdf global elixir 1.11.0
$ asdf shell elixir 1.11.0
$ asdf local elixir 1.11.0

Using the global option will save your choice in $HOME/.tool-versions.

To install a new Elixir version, run asdf install:

$ asdf install elixir 1.11.0

Some plugins might support installing from source with ref:$BRANCH and ref:$COMMIT.

As the Elixir plugin goes, the default is to install precompiled Elixir packages, which is fast!

Because of that, asdf does not need Erlang preinstalled to fetch you Elixir (but you’ll need it for runtime).

My choice

I might recommend trying asdf first if it can do the job. I think the fast way of getting prebuilt Elixir versions is quite lovely!

I am not entirely sold on the one tool approach yet. For example, by using ruby-install instead of ruby-build I can avoid a Ruby requirement (which I prefer). Nothing can be perfect.

by Josef Strzibny