Oct 03, 2018

A note on`application` in mix.exs starting from Elixir 1.4

Estimated Reading Time: 3 minutes (435 words)

Starting from Elixir 1.4, we don’t need to specify our application lists in application. It is automatically inferred from our dependencies. (Check the release notes here)

Do note that it only automatically infer the application lists if the :applications key is empty. If you had already declared your it in your mix.exs like this:

def application do
    # Will be automatically inferred starting
    # from Elixir 1.4, if it is empty.
    applications: [:cowboy, :plug]

Be sure to clear it to utilize this feature.

Below are the detailed story on how I came across this.

Disclaimer: The point of this article is summed up above, skip the part below if you’re busy.

The Story

Recently, I have been writing a simple Plug web application and came across the need to use an external database.

Ecto and PostgreSQl is the thing that come up to my mind.

Hence, I went over the Ecto documentation and run through the setup in the application. After going through the steps, and finally run iex -S mix, an error arise.

...failed to start child: App.Repo

I check my config.exs. Nothing wrong.

So, I go through the documentation again and again, to check if I miss out anything. No, nothing wrong. The documentation didn’t mentioned the need to add ecto and postgrex in the application. After googling around, someone mentioned that adding it solve the issues.

I tried, it worked.

But I don’t know why. The documentation can’t be wrong right?

So, I create a new test application and follow the documentation again.

And, it works.

So, I delete this line of code in my mix.exs:

applications: [:cowboy, :plug]

And, it works.

The Why

Hence, I guess that Mix actaully automatically start the applications needed for us. So, I search through the documentations of different version of Mix (1.4.5 vs 1.3.4), and finally found out that since Elixir 1.4, Mix has this new feature. It is also mentioned in the release notes of Elixir 1.4.

However there is one condition. It only automatically infer the applications list if the :applications key is empty. That explains why it didn’t work in my application because I already declared the list manually, as shown below:

def application do
    mod: {App.App, []},
    extra_applications: [:logger],
    # Can be removed for Elixir >= 1.4.
    # Since it is automatically inferred.
    applications: [:cowboy, :plug]

The Lessons

Thanks for reading through it.