Skip to content

mix_dependencies

Locked Mix dependency graph consumed by Elixir targets.

Description

During graph loading, Once reads a checked-in graph snapshot or asks Mix to evaluate the dependencies active for the configured environment. Once reads package identity from the committed mix.lock and does not run a second version solver. Every active locked Hex or Git dependency becomes a synthetic mix_package target with its own source inputs, build action, and dependency edges.

The lockfile is authoritative. Graph loading fails when an active Mix dependency has no lock entry, when the manifest or lockfile is not included in resolver_inputs, or when a selected source is outside the Once package. When resolver_inputs is empty or omitted, srcs supplies those files instead. Resolution does not fetch sources and never writes mix.lock.

Dependency sources must already exist under vendor_dir, normally deps. This separates network and registry access from build execution. Package build actions enable Hex offline mode and use the locked source tree as declared inputs. Live graph loading uses the vendored source tree and committed lockfile without requiring a separately installed Hex archive.

The aggregate target depends only on the direct roots selected by Mix. The synthetic targets carry transitive edges, so Once still sees and schedules the complete graph. An optional roots list can expose a narrower set by Mix application name or Hex package name.

Attributes

AttributeTypeRequiredDefaultDescription
manifeststringnomix.exsPackage-relative Mix project manifest used to select the active graph
lockfilestringnomix.lockPackage-relative authoritative lockfile
resolver_inputslist<string>nosrcsPackage-relative text globs supplied to the resolver
graph_filestringnoChecked-in JavaScript Object Notation snapshot with exact manifest, lockfile, Mix environment, and resolver input bindings
vendor_dirstringnodepsPackage-relative directory containing fetched dependency source trees
path_dependenciesmap<string, string>no{}Active path dependency application names mapped to first-party Once targets
mix_envstringnoprodMix environment used to evaluate dependency declarations
rootslist<string>no[]Optional application or Hex package names exposed as direct roots
_mix_resolvedboolresolver-ownedfalseMarks a graph expanded from the lockfile
_mix_locked_rootslist<string>resolver-owned[]Records generated root target names

The underscore-prefixed attributes are produced by the resolver and should not be set in once.toml.

Dependency Edges

EdgeAcceptsDescription
depselixir_appDirect locked package roots emitted by the resolver

Transitive package relationships are ordinary deps edges between generated mix_package targets.

Providers

The target emits mix_dependency_set and elixir_app. The elixir_app provider aggregates every reachable package so first-party Elixir targets can consume one dependency edge.

Capabilities

CapabilityOutput groups
buildnone

Example

toml
[[target]]
name = "mix_dependencies"
kind = "mix_dependencies"
srcs = ["mix.exs", "mix.lock", "mix-dependencies.json"]

[target.attrs]
manifest = "mix.exs"
lockfile = "mix.lock"
graph_file = "mix-dependencies.json"
resolver_inputs = ["mix.exs", "mix.lock", "mix-dependencies.json"]
vendor_dir = "deps"

[[target]]
name = "greeting"
kind = "elixir_library"
srcs = ["lib/**/*.ex"]
deps = ["./mix_dependencies"]

The snapshot contains the exact manifest and lockfile text, the selected mix_env, a once_inputs map, the normalized lock object, and a dependencies array. once_inputs contains every exact resolver input except the snapshot itself. Include each path dependency manifest in resolver_inputs. Graph loading rejects any binding that differs from the target. Each dependency records app, dependencies, destination, manager, top_level, path_dependency, and custom_compile. Check in this file to keep ordinary graph queries independent of the Elixir toolchain. Omit it while refreshing dependencies so Mix evaluates the active graph, then review and record the normalized result before restoring tool-free queries.

Map every active path dependency to an ordinary first-party target. The mapped target participates in the imported root and transitive edges instead of being silently omitted:

toml
[target.attrs.path_dependencies]
local_helper = "./local_helper"

Supported Sources and Build Managers

Locked Hex and Git entries are supported. A generated package must use Mix as its build manager. Rebar, Make, and dependency declarations that override the compile command fail explicitly. Dedicated target kinds are required before Once can model those tools and their outputs safely.

The live graph reader requires Erlang 27 or newer for its built-in JavaScript Object Notation encoder. Checked-in snapshots do not require Mix or Erlang during graph loading.

Sources

  • Mix dependencies defines the project dependency forms, environment selection, and native graph behavior.
  • Hex usage explains repeatable fetching and why the lockfile should be committed.
  • Hex package checksums explains the integrity role of package checksums preserved by generated targets.

Released under an open-source license.