As the Phoenix Framework nears a 1.0 release, more and more people are going to want to contribute. That means being able to test changes against the latest code on the master branch. There’s no sense reporting a bug if it’s already been fixed! Let’s find out how to do it.

To get started, I forked the phoenixframework/phoenix repo on GitHub, cloned it locally, and looked at the top-level README file. It says:

Running a Phoenix master app

$ cd installer
$ mix path/to/your/app --dev

So I tried it:

$ cd ~/projects/phoenix
$ cd installer
$ mix ~/projects/my_bleeding_edge_project --dev
** (Mix) --dev version must be inside Phoenix directory

Well… that didn’t work. What does it mean?

After some poking around and IO.inspecting, I figured out that when you create a new Phoenix project with the --dev switch, that project must be created inside the directory containing the Phoenix source code.

The relevant bit of code is at

  defp phoenix_path(path, true) do
    absolute = Path.expand(path)
    relative = Path.relative_to(absolute, @phoenix)

    if absolute == relative do
      Mix.raise "--dev version must be inside Phoenix directory"

To be fair, the instructions DO say path/to/my/project which is a relative path.

So, trying again (remember we’re in the phoenix/installer directory)

$ mkdir projects
$ mix projects/my_bleeding_edge_project --dev

And that works!

What Version?

But… what version of the mix task are we actually using? Presumably before you decided to move to the bleeding edge, you were tracking the latest release, which you have installed locally:

$ ls ~/.mix/archives/phoenix*

So when the version says…

$ mix --version
Phoenix v0.16.1

…is that the one in ~/.mix/archives, or is the one in the directory we’re sitting in? Because phoenix/installers/mix.exs says…

   def project do
     [app: :phoenix_new,
      version: "0.16.1",
      elixir: "~> 1.0-dev"]

…so it’s not clear.

Pre-Release Version Numbers

To get a better idea of what’s going on, and to avoid ever re-building a changed version of an official release, let’s change the version number in that mix.exs file.

But first, since we’ve forked someone else’s repository, we need to move off of the master branch. If I’m not working on anything specific I’ll often just use the date for the branch name.

$ git checkout -b 20150816
Switched to a new branch '20150816'

And now change the version number:

@@ -3,7 +3,7 @@ defmodule Phoenix.New.Mixfile do

   def project do
     [app: :phoenix_new,
-     version: "0.16.1",
+     version: "0.16.2-pre",
      elixir: "~> 1.0-dev"]

Now we’ll be able to tell which one we’re using, and we won’t confuse ourselves by re-building a local 0.16.1 with behavior that differs from the official release.

At this point, mix --version still reports 0.16.1, so we must be using the released version under ~/.mix/archives.

Let’s delete that file.

$ rm ~/.mix/archives/phoenix_new-0.16.1.ez

What version does mix see now?

$ mix --version
Phoenix v0.16.2-pre

Ah ha! Now we’re actually using the code in the installer directory, which means if we want to quickly modify the task itself, we can do so.

Let’s create another project, just in case the task has changed since the 0.16.1 release.

$ mix projects/another_bleeding_edge_project --dev
mix.exs:1: warning: redefining module Phoenix.New.Mixfile
Error while loading project :umbrella_check at /Users/wsmoak/projects/phoenix-wsmoak/installer

(Oops. It thought we were trying to create an umbrella project with multiple modules. Despite the error, it doesn’t seem to have hurt anything.)

Building PhoenixNewTask

Having to delete the official release from ~/.mix/archives isn’t ideal. Can we build the latest version and use it locally without that? There is a README in the installer directory we’re sitting in that says how.

$ MIX_ENV=prod mix
Generated archive phoenix_new-0.16.2-pre.ez with MIX_ENV=prod

$ mix archive.install
Are you sure you want to install archive phoenix_new-0.16.2-pre.ez? [Yn] Y
* creating /Users/wsmoak/.mix/archives/phoenix_new-0.16.2-pre.ez

Well, that puts our development version in ~/.mix/archive, so as expected,

$ mix --version
Phoenix v0.16.2-pre

Anecdotally, if there is an archive in ~/.mix/archives, mix uses that first. Next it looks in lib in the current directory. I’m looking forward to learning more about this in the training class at ElixirConf!


The reason the bleeding edge project has to be created inside the phoenix source code directory can be seen in its (the newly created project’s) mix.exs:

  defp deps do
    [{:phoenix, path: "../../..", override: true},

It wants to use a relative path to find the phoenix dependency. From our location underneath the installer/projects directory we created, it’s backing up three directory levels… which is the top-level of the phoenix source code.

It also overrides any other definition of a dependency on phoenix.


If you’re going to be modifying the task itself, then you’ll probably want to rm ~/.mix/archive/phoenix_new* to make sure you’re only working with the local source code, and do your work from the installer directory.

If you’re patching something in Phoenix outside the installer, then it either may not matter which installer you’re using, or you may wish to build the latest one and install the archive locally.

(It also seems possible to move the newly-created project elsewhere, and modify the path to the Phoenix source code, but I haven’t tried it.)

Now, off to IRC to ask and to either do a PR to improve that error message I got initially, or else find out why it is the way it is!

Copyright 2015 Wendy Smoak - This post first appeared on and is CC BY-NC licensed.