Create an Elixir Phoenix app with asdf

Cameron Carlyle
3 min readFeb 15, 2021
Photo by Steve Johnson on Unsplash

Lately, I’ve been using the asdf as a tool for managing runtime dependencies. It’s a single CLI that can be used for installing and managing the versions of various runtimes. It’s super useful when you are working on multiple projects that have different version dependencies. It’s similar to `rbenv` in Rubyland, except that its a single CLI for multiple runtimes. I use it for everything from Ruby to Elixir to Node.js to Python and even Yarn.

I’m not going to go into detail on how to install or use asdf. They have great docs. But briefly, you can use asdf by creating a .tool-versions file in the root directory of a project. In your .tool-versions file you can list your runtime dependencies and their versions. Running asdf install in same directory of as the .tool-versions file will install the dependencies with the correct versions. Rarely, if ever, do I depend on the globally installed version of runtime dependencies, instead I rely on the versions defined my project's .tool-versions file.

So this is all great when you already have project created, but what do you do when you want to start a new project, a new Elixir Phoenix project for instance, using a code generation tool such as mix phx.new? In order to use mix you need have Erlang and Elixir installed. You could install Erlang and Elixir globally, and use the global versions to create a new Phoenix app. But there's a better way using asdf.

First, install asdf. I used brew, but follow the instructions in the asdf docs.

Next, we need to create directory for our app. I’m going to call my app cam, so I'll create a directory named cam.

$ mkdir ~/code/cam

Next, create a .tool-versions file in the directory you just created.

$ touch ~/code/cam/.tool-versions

Next, we need to add our runtime dependencies to our .tool-versions file. At a minimum, for a Phoenix app, you will need Erlang, Elixir, and Node.js dependencies. Note: Node.js is only needed if you are going to create an app with JavaScript assets. The particular versions you choose is up to you. You can list the available versions using asdf list all <name>, eg.

$ asdf list all erlang

or

$ asdf list all elixir

or

$ asdf list all nodejs

Personally, I prefer to use an Elixir version that is bundled with a specific version of OTP that corresponds to the version of Erlang that I’m installing. In the results of theasdf list all elixir command they are denoted with otp in the version name. For Node.js, I'm choosing to go with a long term support version for this example. So my .tool-versions looks like this:

nodejs lts-fermium
erlang 23.0
elixir 1.11.3-otp-23

With those dependencies saved in the .tool-versions, we can then run the following in the directory where we created the .tool-versions.

$ asdf install

If this is a new Erlang or Elixir version for your machine, you might also need to install the Phoenix application generator. Note: the version might be different whenever you’re reading this. Check out the Phoenix installation docs.

$ mix archive.install hex phx_new 1.5.7

Finally, we are ready to create our Phoenix app. Remember, that we created a directory at ~/code/cam. Normally, when we run mix phx.new <name> the generator will create a new directory with the given <name> and put all of the application files in that directory. Since, we've already created the directory for our application, we can pass the path to that directory to mix phx.new by running the following:

$ mix phx.new ~/code/cam

After running that command, you should be prompted with something like the following:

The directory /Users/cam/code/cam already exists. Are you sure you want to continue? [Yn]

Just type Y, and the Phoenix app should be generated.

Congrats! If all goes as planned, you should be done… or at least ready to get started building your app.

--

--