Create an Elixir Phoenix app with asdf
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.