When working on large Elixir projects, keeping module dependencies clean and acyclic is essential to maintain compile performance and avoid circular references. Elixir provides a helpful tool for this: mix xref.

Here’s a quick command to detect compile-time dependency cycles:

mix xref graph --format cycles --label compile-connected --fail-above 0

What it does:

  • --format cycles: Shows only cyclic dependencies in the module graph.
  • --label compile-connected: Focuses on compile-time references (e.g., module definitions, struct usage, macros).
  • --fail-above 0: Fails the command if any cycle is found (great for CI).

Example output:

== Compilation graph cycle ==
Foo -> Bar -> Baz -> Foo

Compile-time cycles can:

  • Force modules to be recompiled unnecessarily.
  • Introduce brittle dependencies that are hard to test and maintain.
  • Break upgrades in hot code reload scenarios.

Integrate this command in your CI pipeline to prevent new cycles from creeping in:

mix xref graph --format cycles --label compile-connected --fail-above 0

A failing build is a small price to pay for a healthier codebase.