My development cycle looks like:

invent feature ⇒ write test ⇒ implement everything
                                  ⇓           ⇑
                           hack in iex    write more tests
                                  ⇓           ⇑
                                 make tests pass

Right now I’m going to talk about “hack in iex” part. If you are like me, you probably have a good seeds.exs file that feeds the dev database with everything it needs, but… occasionally you tweak the data, and you don’t need a fresh start, and every new single console session starts with annoying Ctrl+R history searches for the data manipulations.

BTW, it you still have no history in your iex console, you are going to upgrade Erlang to version 20 and issue

export ERL_AFLAGS="-kernel shell_history enabled"

somewhere inside your .zsh.after, or .bashrc, or even some fishy script. If you are somehow stuck to erlang version less than 20, check this link. History is a must, no doubt. There is more on enabling history in IEx documentation.

Turning back to iex, one might want to produce a temporary seed, that after the hacking session might be moved to seeds.exs file. To do so, just create a .iex.exs file in the project root directory and put any elixir code you want to get executed when the console starts.

Before we continue with the main example, let me introduce my own .iex.exs file, because it actually has both project-related and system-wide configurations.

global_settings = "~/.iex.exs"
if File.exists?(global_settings), do: Code.require_file(global_settings)

Application.put_env(:elixir, :ansi_enabled, true)
IEx.configure(
 colors: [
   eval_result: [:cyan, :bright] ,
   eval_error: [[:red, :bright, "\n▶▶▶\n"]],
   eval_info: [:yellow, :bright ],
 ],
 default_prompt: [
   "\e[G", # cursor ⇒ column 1
    :blue, "%prefix", :yellow, "|", :blue, "%counter", " ", :yellow, "▶", :reset
  ] |> IO.ANSI.format |> IO.chardata_to_string
)

alias MyApp.{Repo,User,Photo,Album}
[am] = Repo.all User

First two lines enforce the system-wide configuration to be used as “overridable defaults” here. For instance, the whole IEx.configure part might be moved there if you are OK with having same settings for all the projects.

My advise would be: invent the prompt shape you like and put the default_prompt part to system-wide ~/.iex.exs. Don’t be lazy to tune up different colors for each project. That way you’ll never lose the point on what project this console is opened for. If you are working on one project at any moment, you might want to put the whole IEx configuration into system-wide file.

So far so good. This is how my prompt looks like:

iex 1>

One might see the bright red error message. That is configured by [colors: [eval_error: ...]] setting. Everything else is pretty self-explanatory. OK, when we have things tuned up, let’s tweak our project.

When I start to work on some feature, I might need some very filtered set of the data in dev environment, not the wholy load of everything from seeds.exs. I usually start with creating some new data by typing in a console and as soon as I find myself re-evaluating the same line of code from the history more and more, I put the respective line into my project’s .iex.exs file. Or, I might do some clean up after last console session there.

In the example I provided above, last two lines are aliasing everything for my current project and assign the first available user instance from the database to the variable named am. In some projects I have dozens of lines there. For some projects I do not bother to create this file at all, relying on the system-wide one.

Official documentation for IEx.