# Elixir Support in Maguyva: Code Graphs for Phoenix and OTP Apps

Canonical source: https://maguyva.ai/languages/elixir

License: text under [CC BY 4.0](https://creativecommons.org/licenses/by/4.0/); code samples under [MIT-0](https://opensource.org/license/mit-0); the Maguyva name, logos, brand assets and other code are not covered. Details: [maguyva.ai/license](https://maguyva.ai/license).

Maguyva parses Elixir with AST, symbol, and graph support, so AI agents can follow modules, behaviours, protocols, and structs across Phoenix and OTP code.

## Support snapshot

- Tier: AST and symbol support
- Programming
- Extensions: .ex, .exs
- Real AST parsing for syntax-aware search and structural context.
- Named symbols feed semantic lookup and cross-reference. Graph navigation is available when relationship extraction is enabled.
- This language contributes symbols and relationships to graph-aware search; supported edge types vary with its native constructs.
- AST parsing and symbol extraction are both available.

## Best fit

- Phoenix applications where controllers, LiveViews, contexts, and Ecto schemas call each other across many modules.
- OTP systems built from GenServers, supervisors, and tasks.
- Libraries and umbrella projects with protocols implemented for many types.

## Agent workflows

- Find every caller of a context function before changing its return shape.
- List which modules implement a behaviour or protocol before adding a callback.
- Trace a request from a Phoenix controller into the Ecto layer.

## Where Elixir trips up shallow AI tools

Almost everything in Elixir is a macro call. `defmodule`, `def`, `use`, `alias`, and `@impl` all parse as calls, and `use GenServer` brings in behaviour that never appears in the file. A tool that only sees call syntax cannot tell a definition from a dependency, or a GenServer callback from a helper.

Maguyva maps those macros onto relationships, so an agent can see which modules implement a behaviour and who calls a context function.

## What Maguyva extracts in Elixir

Maguyva covers `.ex` and `.exs` files. Elixir's macros map onto relationships:

- `alias`, `import`, and `require` record imports.
- `use` records an import. For OTP and framework behaviours such as `GenServer`, `Supervisor`, `Agent`, `Task`, `Phoenix.Controller`, `Phoenix.LiveView`, and `Ecto.Schema`, it also records that the module implements that behaviour.
- `@behaviour` attributes and `defimpl` blocks record implementation of a behaviour or protocol.
- Reserved module attributes such as `@doc`, `@spec`, `@impl`, and `@callback` are recorded as annotations on the function that follows. Value attributes such as `@timeout 5_000` are not.
- `%User{}` struct literals count as instantiation, `raise` records a throw, and `rescue` and `catch` record a catch.

Language macros such as `def`, `defp`, `defmodule`, `case`, and `with` are filtered from calls, so the call graph shows your functions.

## Example agent prompts

- "Who calls `Accounts.register_user`, and from which controllers?" (`find_symbol`, then `dependency_search` incoming)
- "Which modules implement `GenServer`?" (`dependency_search`)
- "Trace a checkout request from the controller to the database." (`get_task_context`)

## Known limits

- Named `def`, `defmodule`, `alias`, and `import` forms are call nodes in the grammar, so only the `functions` preset in `structural_search` returns results, and only for anonymous `fn` functions. Use `find_symbol` for named functions and modules.
- About 55 standard-library calls, such as `IO.puts`, `String.*`, `Enum.take`, and `Process.*`, are filtered from relationships. Use `text_pattern_search` for them.
- Elixir has no class inheritance, so inheritance relationships are marked not applicable.

## Next steps

Connect a repository with the [quickstart](/docs/quickstart), then check the support matrix on the [compatibility page](/docs/compatibility). For other functional codebases, read the [Haskell guide](/languages/haskell).

## Engine details

- Elixir support covers `.ex` and `.exs`. `alias`, `import`, `require`, and `use` record imports.
- `use GenServer` and other listed OTP and framework behaviours, `@behaviour`, and `defimpl` record implementation relationships.
- Reserved attributes such as `@spec` and `@impl` annotate the next function, and `%Struct{}` literals count as instantiation.

## Useful MCP entry points

- `find_symbol`: Use it for a context function or module when you need the definition and callers; structural presets do not select named `def` forms.
- `dependency_search`: Use incoming traversal on a behaviour or protocol to see which modules implement it.
- `get_task_context`: Use it for prompts like “trace a checkout request from the controller to the database.”
