ecto
Design and debug Elixir persistence with Ecto. Use for schemas, changesets, queries, preloads, transactions, migrations, multi-tenancy, and data access through…
Write and refactor idiomatic Elixir functions, modules, and data structures. Use for pattern matching, control flow, error handling, protocols, behaviours, and deciding whether a process is needed. Use otp for process design and supervision.
$ npx -y skills add georgeguimaraes/claude-code-elixir --skill elixir --agent claude-codeHow it fires
How this skill gets triggered: by you, by Claude, or both.
/elixirContext preview
The summary Claude sees to decide when to auto-load this skill.
Write and refactor idiomatic Elixir functions, modules, and data structures. Use for pattern matching, control flow, error handling, protocols, behaviours, and deciding whether a process is needed. Use otp for process design and supervision.
name: elixir description: Write and refactor idiomatic Elixir functions, modules, and data structures. Use for pattern matching, control flow, error handling, protocols, behaviours, and deciding whether a process is needed. Use otp for process design and supervision.
Design modules, model data, and handle errors with Elixir's functional idioms.
NO PROCESS WITHOUT A RUNTIME REASON
Before creating a GenServer, Agent, or any process, answer YES to at least one: 1. Do I need mutable state persisting across calls? 2. Do I need concurrent execution? 3. Do I need fault isolation?
**All three are NO?** Use plain functions. Modules organize code; processes manage runtime.
OOP couples behavior, state, and mutability together. Elixir decouples them:
| OOP Dimension | Elixir Equivalent | |---------------|-------------------| | Behavior | Modules (functions) | | State | Data (structs, maps) | | Mutability | Processes (GenServer) |
Pick only what you need. "I only need data and functions" = no process needed.
The misconception: Write careless code. The truth: Supervisors START processes.
**Pattern matching first:**
**Error handling:**
**Be explicit about expected cases:**
# Verbose
case get_run(id) do
{:ok, nil} -> nil
{:ok, run} -> run.recommendations
end
# Prefer
with {:ok, %{recommendations: recs}} <- get_run(id), do: recs| For Polymorphism Over... | Use | Contract | |--------------------------|-----|----------| | Modules | Behaviors | Upfront callbacks | | Data | Protocols | Upfront implementations | | Processes | Message passing | Implicit (send/receive) |
**Behaviors** = default for module polymorphism (very cheap at runtime) **Protocols** = only when composing data types, especially built-ins **Message passing** = only when stateful by design (IO, file handles)
Use the simplest abstraction: pattern matching → anonymous functions → behaviors → protocols → message passing. Each step adds complexity.
**When justified:** Library extensibility, multiple implementations, test swapping. **When to stay coupled:** Internal module, single implementation, pattern matching handles all cases.
OOP: Complex class hierarchy + visitor pattern. Elixir: Model as data + pattern matching + recursion.
{:sequence, {:literal, "rain"}, {:repeat, {:alternation, "dogs", "cats"}}}
def interpret({:literal, text}, input), do: ...
def interpret({:sequence, left, right}, input), do: ...
def interpret({:repeat, pattern}, input), do: ...Use `/3` variants (`Keyword.get/3`, `Map.get/3`) instead of case statements branching on `nil`:
# WRONG case Keyword.get(opts, :chunker) do nil -> chunker() config -> parse_chunker_config(config) end # RIGHT Keyword.get(opts, :chunker, :default) |> parse_chunker_config()
Don't create helper functions to merge config defaults. Inline the fallback:
# WRONG defp merge_defaults(opts), do: Keyword.merge([repo: Application.get_env(:app, :repo)], opts) # RIGHT def some_function(opts) do repo = opts[:repo] || Application.get_env(:app, :repo) end
**Inside coding agents, always prefix `mix` commands with `unbuffer`** to get ANSI colors and prevent stdout block-buffering in non-TTY environments (e.g. `unbuffer mix test`). Install: `brew install expect` (macOS) or `apt install expect` (Linux). If `unbuffer` is unavailable, report the missing prerequisite instead of silently dropping it.
After changing Elixir code, verify the completed change before reporting it as done. Run commands from the relevant Mix project using its pinned Elixir/OTP versions. Follow the repository's contribution instructions and existing check aliases. Prefer an alias when it covers the checks below, and run any uncovered checks separately:
1. Format changed files with `unbuffer mix format path/to/file.ex path/to/test.exs`, following the project's formatter configuration. 2. Compile with `unbuffer mix compile --warnings-as-errors` to catch compilation errors and warnings. 3. Run relevant tests with `unbuffer mix test test/path/to/affected_test.exs`. Run the broader suite when the change affects shared behavior or the repository requires it. 4. Run `unbuffer mix credo` when Credo is configured, using the repository's flags and configuration.
Fix failures introduced by the change and rerun the affected checks. Report the commands actually run and their results, including any checks that were skipped or blocked and why. An unrun or blocked check hasn't passed.
**Prefer pattern matching over imperative assertions.** Never use `assert length` + `Enum.at`/`List.last`/`hd`. Pattern match checks le
Elixir development guidance for coding agents, with optional Mix checks and Expert language server integration. Install the elixir-dev plugin for five skills covering language idioms, Phoenix interfaces, Ecto persistence, OTP processes, and Oban jobs.
Design and debug Elixir persistence with Ecto. Use for schemas, changesets, queries, preloads, transactions, migrations, multi-tenancy, and data access through…
Build and debug durable background jobs with Oban and Oban Pro. Use for workers, job argument serialization, retries, scheduled or recurring jobs, uniqueness,…
Design and debug Elixir runtime concurrency, process state, and supervision. Use for GenServer, Supervisor, Task, Registry, ETS, process bottlenecks, and…
Build and debug Phoenix web interfaces and HTTP endpoints. Use for LiveView lifecycle and data loading, components, forms, routes, controllers, Plug, channels,…