How to deal with Elixir version in `mix.exs` vs. the global Elixir version?

After creating a Phoenix project, mix.exs has:
elixir: "~> 1.12"

However, running elixir -v outputs:

Erlang/OTP 25 [erts-13.0.3] [source] [64-bit] [smp:8:8] [ds:8:8:10] [async-threads:1] [jit] [dtrace]

Elixir 1.14.0 (compiled with Erlang/OTP 25)

What is the best practice in these scenarios?
Is it to use a version manager like asdf to set the local Elixir version to match 1.12 like what’s in mix.exs?
Or is it to change the 1.12 in mix.exs to match the 1.14 global Elixir version?

It depends. The :elixir key in mix.exs make sense only for libraries and as sanity check. Otherwise you do not need to care much about it.


When you say “libraries”, do you mean if I am creating a library, I should put the elixir version that my library was created with?

Or do you mean that the libraries in my dependencies will rely on the elixir version specified in mix.exs?

When creating a library, you should put the minimum Elixir version that your library is tested with for compatibility. There are techniques for conditionally compiling additional library features based on the presence of certain features, so you may have a library that requires ~> 1.12 but has some features that require a later version of Elixir (or OTP) — those features may just be unusable on 1.12.

If are working on a team, however, you will want to use something like the asdf version manager and a .tool_versions file checked into the repository specifying the same Elixir and OTP versions that your app will use in production.