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
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. I used brew, but follow the instructions in the
Next, we need to create directory for our app. I’m going to call my app
cam, so I'll create a directory named
$ 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
asdf list all <name>, eg.
$ asdf list all erlang
$ asdf list all elixir
$ 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 the
asdf 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:
With those dependencies saved in the
.tool-versions, we can then run the following in the directory where we created the
$ 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]
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.