cult3

Organising your Elixir project with Mix

Aug 31, 2016

Table of contents:

  1. What is Mix?
  2. Creating a new project
  3. Naming conventions of Mix applications
  4. Writing tests
  5. Compiling and Running in iex
  6. What are Umbrella Projects?
  7. Conclusion

We have already covered a lot of ground so far in this exploration of Elixir, but in just about every example we’ve been running our Elixir code either in iex or from a single file.

This is fine for getting to grips with the language and for very simple examples, but we’re going to need something else if we want to manage more complex projects.

In Elixir the answer to this problem is Mix.

Mix is a set of tools for creating, testing, and building your application. It will also handle your dependencies and it is packaged with the language.

In today’s tutorial we are going to be looking at using Mix to manager our Elixir projects.

What is Mix?

When it comes to building applications, there are certain tools that greatly increase your developer productivity. In most languages, these tools are often built by the community, but they are usually as important as the language itself.

Mix is a set of tools for creating, testing, and building your Elixir application. If you are coming from a Ruby background, you can think of Mix as a combination of Rake, Bundler, and Ruby Gems.

You will use Mix to create a new Elixir project, manage it’s dependencies, and compile it ready for deployment.

Mix also deals with including your code from .ex files from folders in the lib directory. And it can also help you split code into “Umbrella Projects”.

Another interesting aspect of Mix is that it ships with ExUnit, a testing framework. And so when you create a new Mix project, you’ve already got everything you need to start building an Elixir application.

If you have Elixir installed on your computer you already have Mix installed as it is shipped as part of the language.

Creating a new project

One of the first things you will need Mix for is to create yourself a new project. Run the following in your terminal:

mix new hello

This will create a new directory called hello with a number of files and directories that form the convention of an Elixir project.

Using a command line tool for creating a new project is a much better way than copying the files and structure from a previous project (or a tutorial like this) and it will save you a lot of headache when you inevitably make a small mistake.

Mix will also automatically generate a .gitignore and a README.md so you have already got everything you need to get going with your new project.

Under the config directory you will find a config.exs file for setting any configuration options you might have.

Under the lib directory is where you will put the code of your application. You will see that Mix has automatically created a new file named using the identifier you provided Mix when creating the application, in my case hello.ex:

defmodule Hello do
end

And finally you have a test directory which is where you will write your tests. I’ll speak more about writing tests later in this article.

Naming conventions of Mix applications

Up until this point we have mostly been writing code in iex or stuffing all of our code into a single file.

Mix allows you to structure your code in a more organised fashion, and it will deal with loading your code correctly when the application is complied.

There are a couple of naming conventions that you would stick to:

  • Use a top level module to prevent naming collisions
  • Each module should be in a single file, and each file should have a single module
  • File names should be snake cased
  • Module names should be camel cased
  • The folder structure should mirror the module names

Writing tests

Writing tests is a really important part of building high quality applications and so Elixir ships with a testing framework as part of the language.

When you generated your new Mix project, a test directory was created with files named test_helper.exs and hello_test.exs.

The test_helper.exs file is where you can set up any configuration type stuff you might need for your tests, and the hello_test.exs file is automatically generated as a place to write tests for your top level module:

defmodule HelloTest do
  use ExUnit.Case
  doctest Hello

  test "the truth" do
    assert 1 + 1 == 2
  end
end

As you can see, we already have a test that was generated by Mix and so we can run the tests to see them pass. Run the following command in terminal to run the tests:

mix test

You can also run your tests with the --trace flag to see a more detailed report:

mix test -trace

We will be taking a much deeper dive into testing with Elixir and ExUnit in a future article so I won’t go into any more detail at this stage.

Compiling and Running in iex

Once you’ve written some code you will probably want to compile it and play with it in iex to see if it’s working as it should be.

For the sake of demonstration purposes, lets add a simply function to the Hello module:

defmodule Hello do
  def greet do
    IO.puts("Hello World")
  end
end

To compile the project you would run the following command in terminal:

mix compile

This will create a new directory called _build that will contain the compiled .beam files.

You can also compile and load your application into iex so you can play with it from the command line. To do that you would run the following command in terminal:

iex -S mix

This will drop you into iex with your code compiled and ready to go.

What are Umbrella Projects?

One of the most interesting aspects of Mix is the functionality to create “Umbrella Projects”.

In Elixir, an application is a set of modules that can be started and stopped as one. The Erlang virtual machine encourages you to split your code up into independent applications.

You can think of each application as a “micro service”, and so a typical web application might be comprised of many independent Elixir applications.

Mix makes it easier to manage these independent Elixir applications through umbrella projects.

An umbrella project allows you to manage all of your Elixir applications under one repository. This enables you to compile and test as one project, or as independent applications, getting the best of both micro services and monolith architectures.

To create an umbrella project you would use the --umbrella flag when creating a new project:

mix new killer_app -umbrella

This will create a simplified version of the normal project structure we looked at earlier.

Inside of an umbrella project you will find an apps directory. In this directory is where you would run the mix new command for each of the applications of your project.

Mix will automatically detect that you are running this command from within an umbrella project and it will automatically configure the generated applications correctly for you.

Conclusion

Mix is one of the many reasons why developer experience is so good with Elixir. It provides all of the tools you will need to get started writing, building, and testing your Elixir project. And it all comes as part of the language so you don’t need to set it up for yourself.

Probably one of the most interesting aspects of Elixir projects is how umbrella projects work. When I realised that this was possible, suddenly a lot of the practical considerations of building a micro services application began to fall into place.

As we continue to explore the world of building Elixir applications we will no doubt cover many of the edge cases of using Mix. But hopefully that was a good introduction to what you can expect from the Elixir tool belt.

Philip Brown

@philipbrown

© Yellow Flag Ltd 2024.