Mix.env() doesn't work in releases

almirsarajcic

almirsarajcic

yesterday

0 comments

Mix.env() doesn’t exist in production releases. Your conditional routes will silently fail, and you won’t know until deployment. Use Application.compile_env/2 instead.

# ❌ WRONG: Mix.env() doesn't exist in releases
if Mix.env() == :dev do
  scope "/dev" do
    pipe_through(:browser)
    forward("/mailbox", Plug.Swoosh.MailboxPreview)
  end
end

# ✅ CORRECT: Use compile_env for conditional routes
if Application.compile_env(:my_app, :env) == :dev do
  scope "/dev" do
    pipe_through(:browser)
    forward("/mailbox", Plug.Swoosh.MailboxPreview)
  end
end

The Mix module is a build tool - it’s not included in production releases. When you deploy with mix release, any code calling Mix.env() will crash with UndefinedFunctionError.

The fix

Store your environment at compile time in config/config.exs:

# config/config.exs
config :my_app, :env, config_env()

Then use Application.compile_env/2 in your router:

# router.ex
if Application.compile_env(:my_app, :env) == :dev do
  scope "/dev" do
    pipe_through(:browser)
    forward("/mailbox", Plug.Swoosh.MailboxPreview)
    live_dashboard("/dashboard", metrics: MyAppWeb.Telemetry)
  end
end

When to use each function

Function When Example
config_env() Config files only config/config.exs, config/runtime.exs
Application.compile_env/2 Compile-time decisions Router conditionals, module attributes
Application.get_env/2 Runtime values Reading config in functions

Common patterns that break in releases

  • if Mix.env() == :test for test-only routes
  • @some_attr if Mix.env() == :prod, do: X, else: Y
  • Logger.level(if Mix.env() == :dev, do: :debug, else: :info)

All of these need Application.compile_env/2 instead.

Comments (0)

Sign in with GitHub to join the discussion