Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

In an Elixir project, mix.exs holds project metadata, OTP application settings, and dependency declarations. Put build- and environment-specific configuration in config/; use config/runtime.exs for values that must be read when an application or release starts. The setup below covers adding dependencies, checking their resolution, and deciding whether related applications belong in an umbrella.

What belongs in mix.exs?

Mix is Elixir’s build tool for creating, compiling, and testing projects and managing dependencies, as described in the Mix reference. A project commonly defines a module using Mix.Project in its root mix.exs file. Mix loads this file to obtain the project’s settings, so keep its configuration straightforward.

The main callbacks have distinct jobs:

  • project/0 returns a keyword list of project settings, commonly including :app, :version, and :deps.
  • application/0 configures the generated OTP application. For example, it can list OTP applications such as :logger under :extra_applications.
  • A private deps/0 function can return the dependency list referenced by the :deps setting.

Mix uses project app and version metadata when compiling the OTP .app file. Runtime applications are generally inferred from dependencies unless configured otherwise; details can vary by Mix version, so check the documentation for the version used by your project. See the compile.app documentation.

How to add and inspect a dependency

Add dependencies to the list returned by deps/0. Hex is the usual source for a published package; Mix also supports Git repositories, local paths, and sibling applications in an umbrella.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
  1. Open the project file. Edit the root mix.exs and find or add the deps/0 function.
  2. Declare the dependency. For example, a Hex package can be declared as {:plug, "~> 1.0"}. Choose a version requirement appropriate for the package and your project rather than copying the illustrative version blindly.
  3. Fetch dependencies. Run mix deps.get from the project directory.
  4. Check status or relationships. Run mix deps to list dependency status or mix deps.tree to inspect the dependency tree.
  5. Commit the application lockfile. The lockfile records the resolved dependency versions for the application. Mix ignores a project’s lockfile when that project is itself being used as a dependency; its lockfile does not pin versions for downstream consumers.

Consult the versioned Mix dependency task documentation for task behavior. In Mix v1.20.0 and later, mix deps can filter by dependency names; for example, Mix v1.20.4 accepts mix deps phoenix phoenix_live_view. Confirm flags and filtering behavior against the Mix version installed for your project.

Choose a dependency source and requirement

Dependency source affects where code comes from and how you manage its version. The declaration examples below follow the forms described in the Mix dependency documentation.

Source Example What to consider
Hex package {:plug, "~> 1.0"} Use an explicit version requirement. The requirement expresses which versions your project accepts; it does not prove that every matching version has been tested.
Git repository {:some_lib, git: "https://example.invalid/some_lib.git", tag: "v1.0.0"} Mix supports selecting a tag, branch, or reference. Choose a reference that matches your update and reproducibility needs.
Local path {:local_lib, path: "../local_lib"} Useful when the dependency is a nearby project under active development. The path must be available in the environment where the project is built.
Umbrella sibling {:sibling_app, in_umbrella: true} Use this form for a sibling application managed as part of the same umbrella project.

Pay attention to the upper bound implied by the pessimistic version operator ~>. The Elixir Version documentation gives these examples: ~> 2.0.0 means >= 2.0.0 and < 2.1.0, while ~> 2.0 means >= 2.0.0 and < 3.0.0. The number of components after the first part changes the permitted range. Other requirement operators include >=, <, <=, and ==.

Set dependency scope and runtime behavior

Options on a dependency declaration control where it applies and how it participates in the application:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
  • :only limits a dependency to specified Mix environments, such as :test.
  • :targets limits it to specified targets.
  • :optional means downstream consumers are not forced to include that dependency.
  • :runtime controls whether the dependency participates as a runtime application.

Dependencies generally run in :prod by default, even when the parent project is running in :dev. Do not assume that every dependency inherits the current project environment; use explicit options when scope matters and consult the installed Mix version’s dependency documentation.

Configure build-time and runtime values

Configuration files serve different stages of a project’s life. Mix and build-time work evaluate config/config.exs and any environment files it imports. A common arrangement imports a file selected with config_env(), such as config/dev.exs or config/test.exs. See the Mix configuration guide.

config/runtime.exs is evaluated before applications start in both Mix and releases. Put values there when they need to come from the environment at startup, such as deployment-specific settings. Avoid requiring production secrets during compilation: a build host may not have those values, and compile-time configuration changes can require recompilation. The Config and releases documentation explains the distinction and cautions that application environment is global storage. A dependency’s own config/config.exs is not evaluated as the consuming project’s configuration, so library authors should not rely on it to configure an application that uses their library.

Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

When an umbrella project makes sense

An umbrella groups multiple OTP applications in one repository, commonly under apps/. The applications typically share build, configuration, dependency, and lockfile locations. A sibling application can depend on another with {:sibling_app, in_umbrella: true}.

What’s actually slowing this PC down?

Pick the symptom - the matching free tool is one click away.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

This structure is useful when related applications benefit from shared project management. If applications need different dependency versions or substantially different configuration, shared umbrella state can become a poor fit. The Mix.Project guide describes alternatives such as standalone projects with path dependencies in one repository, private Git repositories, or private Hex.pm organizations.

Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.