The docs say @requirements ["app.config"] should be sufficient, but that gave me this error:

(RuntimeError) could not lookup App.Repo because it was not started or it does not exist

UPDATE: app.start instead of app.config does work! I’ve submitted a PR.

I also tried using Mix.Ecto.ensure_started(App.Repo, []) and App.Repo.start_link(), which didn’t work.

Finally, a post from 2019 on the Elixir forums suggested using Ecto.Migrator.with_repo/21, which did work:

defmodule Mix.Tasks.App.SomeTask do
  use Mix.Task
  @impl Mix.Task
  def run(_args) do
    {:ok, _, _} = Ecto.Migrator.with_repo(App.Repo, fn (_repo) ->
      IO.inspect App.Repo.all(App.SomeModel)
    end)
  end
end

So far Phoenix is nifty; it feels like the first new web framework written by someone who has actually used Rails or Django and then decided which parts they like and don’t like. This makes sense because the creator of Elixir, JosĂ© Valim, was one of the creators of Devise, the most popular auth system for Rails!

In contrast, a lot of the strange decisions in Next.js/Prisma etc. seem like they were made by people who hadn’t used Rails before—for example, the creator of Next.js said: “The reason you probably miss ActiveRecord is that we certainly didn’t start there, and given it was a focus for Rails, it’s probably amazing.” I don’t want to bash on Next.js—it’s very impressive technology—but having used both, Rails is so much more effective that I reach for it in spite of liking TypeScript much much more than Ruby.


  1. It seemed a little weird to use a function from Ecto.Migrator even though I’m not running a migration—I wouldn’t want to trigger some automatic migration bookkeeping system. But the documentation says: “Although this function was designed to start repositories for running migrations, it can be used by any code, Mix task, or release tooling that needs to briefly start a repository to perform a certain operation and then terminate.” ↩︎