Agent skill

Elixir

by ericrisco in ericrisco/rsc-harness

A skill your agent uses when writing or refactoring Elixir/OTP on the BEAM — GenServers, supervision trees and restart strategies, pattern matching, mix projects and releases — or when processes…

MITAuto-check passedDevelopment

Install Elixir

skills CLI
$ npx skills add ericrisco/rsc-harness --skill elixir -a claude-code

Project install by default; add -g for ~/.claude/skills/.

GitHub CLI
$ gh skill install ericrisco/rsc-harness elixir --agent claude-code

Project scope by default; add --scope user for a personal install. Needs GitHub CLI 2.90.0 or later (public preview).

Manual copy
$ git clone --depth 1 https://github.com/ericrisco/rsc-harness.git skills-src && mkdir -p .claude/skills && cp -r skills-src/skills/elixir .claude/skills/elixir && rm -rf skills-src

Use ~/.claude/skills/ instead of .claude/skills for a personal install. The folder must contain SKILL.md.

Claude Code skills documentation · loads skills from .claude/skills/

Facts

Skill name
elixir
GitHub stars
167
Token cost
~2.9k tokens
SKILL.md length
1,215 words
Files
6 (incl. scripts, references)
Skills in repo
227
Repo updated
First seen
Licence
MIT

At a glance

A skill your agent uses when writing or refactoring Elixir/OTP on the BEAM — GenServers, supervision trees and restart strategies, pattern matching, mix projects and releases — or when processes…

  • Refactoring Elixir/OTP on the BEAM — GenServers
  • SKILL.md covers Decision: do you even need a…, The functional core, Processes and message passing and GenServer, plus 5 more sections
  • Runs Shell scripts from its folder
  • Supervision trees and restart strategies

What it does

Elixir is an agent skill from ericrisco/rsc-harness. Use when writing or refactoring Elixir/OTP on the BEAM — GenServers, supervision trees and restart strategies, pattern matching, mix projects and releases — or when processes misbehave (restart loops, mailbox growth, call timeouts). NOT a Phoenix web app, LiveView, Ecto or channels (that is phoenix).

Its SKILL.md is about 2.9k tokens, which your agent loads only when the skill is triggered. The skill folder holds 8 other files, including scripts and reference files (for example `evals/README.md`, `evals/cases.yaml` and `references/mix-and-releases.md`).

It sits in Development, covering LLM observability and Refactoring. It works with Elixir. The repository describes itself as: Your agent invents things because it has no memory, and can't touch your database because it has no arms. rsc is the meta-harness that gives it both, plus the trade to know the… The licence is MIT.

When your agent uses it

  • Refactoring Elixir/OTP on the BEAM — GenServers
  • Supervision trees and restart strategies
  • Pattern matching
  • Mix projects and releases —

Example prompts

  • “/elixir”

Requirements

  • A Bash shell
  • Docker

What it can do on your machine

Read from SKILL.md and the folder at commit e3d5b33. It shows what the files ask for, not the result of running them.

  • Tool permissions

    Pre-approves nothing: there is no allowed-tools line, so your agent's usual permission prompts apply.

    From allowed-tools in the SKILL.md frontmatter.

  • Runs code

    Ships 1 file in scripts/ (Shell), which the agent can run.

    From the folder's file list and the shell code blocks in SKILL.md.

  • Network

    No URLs in SKILL.md.

    From URLs in SKILL.md, links to its own repository left out.

  • Credentials

    Names no API keys, tokens, secrets or passwords.

    From names ending in _API_KEY, _TOKEN, _SECRET, _KEY or _PASSWORD in SKILL.md.

Context cost

Elixir loads about 2.9k tokens when it runs, and up to ~4.8k if it reads all its reference files. Until then it costs about 78 tokens; SKILL.md has 1,215 words of instructions outside code blocks.

Always · name and description, kept in context so the agent knows when to use it
~78
When it runs · the whole SKILL.md, loaded when a task matches
~2.9k
With references · SKILL.md plus every file in references/, read only if the agent opens them
~4.8k

Estimates: characters ÷ 4, the usual rule of thumb; real counts depend on the model's tokenizer. Scripts and assets cost tokens only if the agent reads them.

Safety

Auto-check passed

The automated check found no risky patterns in SKILL.md.

Automated static check — not a guarantee. Review scripts before installing. It scans the text of SKILL.md for risky patterns (piping downloads into a shell, reading credential files, hidden Unicode, destructive commands); the scripts in this folder are not scanned.

SKILL.md

The full file from ericrisco/rsc-harness at commit e3d5b33, republished under its MIT licence (© ericrisco). 1,215 words, ~2,925 tokens.

Download SKILL.mdSave it as .claude/skills/elixir/SKILL.md (or your agent's skills folder). This skill also uses 5 other files; get the full folder from GitHub.
name
elixir
description
Use when writing or refactoring Elixir/OTP on the BEAM — GenServers, supervision trees and restart strategies, pattern matching, mix projects and releases — or when processes misbehave (restart loops, mailbox growth, call timeouts). NOT a Phoenix web app, LiveView, Ecto or channels (that is `phoenix`).
tags
elixir, otp, genserver, supervision, beam, mix, concurrency, functional
recommends
phoenix, postgresdb, docker
origin
risco

Elixir

You are writing Elixir on the BEAM. The runtime gives you cheap isolated processes, preemptive scheduling, and supervision. The single mental shift that separates idiomatic Elixir from ported imperative code: let it crash and supervise it, do not defend every call. A process that hits an impossible state should die and be restarted clean by its supervisor — that is more correct than a try/rescue that limps on with corrupt state.

Default to pure functions. Most of your code is data transformation and needs no process at all. Reach for a process only when you need state, concurrency, or fault isolation. Target Elixir v1.19.5 (stable, requires Erlang/OTP 28.1+) or v1.20-rc (full type inference, OTP 27+/29). Use the modern stdlib: built-in JSON, set-theoretic type warnings, mix format.

Decision: do you even need a process?

A process is not "an object": spawning one to hold a value you could pass as an argument is the most common beginner mistake, and it adds a serialization bottleneck and a failure mode for nothing.

SituationUseWhy
Pure transform of input -> outputplain function / moduleNo state, no concurrency: a process only adds overhead and a mailbox
Hold mutable state behind an APIGenServer (or Agent for trivial state)Serializes access, owns a lifecycle, supervisable
Run N independent jobs concurrentlyTask.async_stream / Task.SupervisorBounded fan-out, results collected, crashes isolated
Isolate a risky/external boundarya supervised processA crash there restarts clean without taking down callers
Shared read-heavy cache:ets tableConcurrent lock-free reads, no single-process bottleneck

Rule: if two pieces of code never run at the same time and share no mutable state, they are functions, not processes.

The functional core

Match in function heads, not with if — branches become exhaustive and self-documenting, and a non-match crashes loudly instead of silently falling through.

elixir
# Bad - imperative branching, easy to miss a case
def area(shape) do
  if shape.type == :circle do
    :math.pi() * shape.r * shape.r
  else
    shape.w * shape.h
  end
end

# Good - one clause per shape, unmatched input crashes (which a supervisor handles)
def area(%Circle{r: r}), do: :math.pi() * r * r
def area(%Rect{w: w, h: h}), do: w * h

Return tagged tuples {:ok, value} / {:error, reason} — the caller pattern-matches the outcome; this is the protocol the whole ecosystem speaks.

elixir
# Good
def fetch(id) do
  case Repo.get(id) do
    nil -> {:error, :not_found}
    record -> {:ok, record}
  end
end

Chain fallible steps with with — it reads as the happy path and short-circuits on the first non-match, no nested case pyramids.

elixir
# Good - any step returning a non-{:ok, _} falls straight to else
with {:ok, user} <- fetch_user(id),
     {:ok, acct} <- fetch_account(user),
     :ok <- authorize(acct) do
  {:ok, acct}
else
  {:error, reason} -> {:error, reason}
end

Use guards to constrain clauses (when is_integer(n) and n > 0) — keeps validation declarative and lets the compiler reason about types.

Pipe left-to-right for data flowing through transforms — data |> step1() |> step2(). Do not pipe just to avoid an intermediate variable; if a step needs the value in a non-first argument, name it.

There is no mutation. Rebinding x = f(x) makes a new binding; data you passed elsewhere is unchanged. Stop reaching for mutable accumulators — use Enum.reduce/3, comprehensions, or recursion.

Processes and message passing

Raw spawn/send/receive exists and is fine for a throwaway fire-and-forget where supervision genuinely does not matter, but in production you almost always want an OTP behaviour (GenServer/Task/Agent) so you get child_spec, supervision, and shutdown handling for free.

  • Link (spawn_link) couples lifetimes: if one dies abnormally, the other gets an exit signal. This is how supervision works.
  • Monitor (Process.monitor/1) is one-directional and non-fatal: you get a {:DOWN, ...} message but you do not die. Use it when you care that something died but should survive it.

GenServer

Split the client API (runs in the caller) from the server callbacks (run in the GenServer process). Callers never touch state directly.

elixir
defmodule Counter do
  use GenServer

  # --- Client API (caller's process) ---
  def start_link(opts) do
    GenServer.start_link(__MODULE__, opts[:start] || 0, name: opts[:name] || __MODULE__)
  end

  @spec increment(GenServer.server()) :: :ok
  def increment(server \\ __MODULE__), do: GenServer.cast(server, :increment)

  @spec value(GenServer.server()) :: integer()
  def value(server \\ __MODULE__), do: GenServer.call(server, :value)

  # --- Server callbacks (GenServer's process) ---
  @impl true
  def init(start), do: {:ok, start, {:continue, :warm_up}}

  @impl true
  def handle_continue(:warm_up, state) do
    # heavy/slow init goes here, AFTER start_link has returned
    {:noreply, state}
  end

  @impl true
  def handle_cast(:increment, count), do: {:noreply, count + 1}

  @impl true
  def handle_call(:value, _from, count), do: {:reply, count, count}
end
  • Never block in init/1. start_link blocks until init returns, so a slow init stalls the whole supervision tree boot. Return {:ok, state, {:continue, term}} and do the work in handle_continue/2.
  • use GenServer auto-defines child_spec/1 — you rarely write one by hand; override only to change :restart or :shutdown.
  • call is synchronous (with a 5s default timeout), cast is fire-and-forget. Use call when the caller needs the result or backpressure; cast when it does not. A flood of casts with no backpressure is the classic mailbox-growth bug — timeouts and backpressure recipes in references/otp-patterns.md.
  • Name via Registry, not a global atom, when you have many dynamic instances — atoms are never garbage-collected (see anti-patterns).
Show full SKILL.md (578 more words)Show less

Supervision trees

The supervision tree starts in lib/<app>/application.ex, wired via the mod: key in mix.exs. mix new <app> --sup scaffolds this.

elixir
defmodule MyApp.Application do
  use Application

  @impl true
  def start(_type, _args) do
    children = [
      {Registry, keys: :unique, name: MyApp.Registry},
      {DynamicSupervisor, name: MyApp.WorkerSup, strategy: :one_for_one},
      Counter
    ]

    Supervisor.start_link(children, strategy: :one_for_one, name: MyApp.Supervisor)
  end
end

Restart strategy — how siblings react when one child dies:

StrategyOn a child crashUse when
:one_for_onerestart only that childchildren are independent (the default, most common)
:one_for_allrestart all childrenchildren depend on each other and shared state is invalidated
:rest_for_onerestart that child and the ones started after itlater children depend on earlier ones

Restart value per child — :permanent (always restart, the default), :transient (restart only on abnormal exit), :temporary (never restart). A pool worker is often :transient; a one-shot job is :temporary.

Let it crash: do not wrap business logic in try/rescue to keep a process alive. Validate inputs at the boundary, then trust the happy path; if an invariant breaks, crashing and restarting from a known-good init state is the recovery mechanism. Reserve rescue for boundaries where you must convert an exception into a tagged tuple for a caller.

For runtime-spawned children (a worker per connection/job) use DynamicSupervisor + Registry for lookup. Full recipe — plus Task, Agent, :ets and how to choose an OTP behaviour — in references/otp-patterns.md.

mix project

text
my_app/
  mix.exs               # project, deps, application/0 with mod: callback
  config/
    config.exs          # compile-time config (read once, at build)
    runtime.exs         # runtime config — reads System.get_env at boot
  lib/
    my_app.ex
    my_app/
      application.ex     # supervision tree
  test/
  • config.exs is compile-time; runtime.exs is runtime. Anything coming from the environment of the running release (DB URL, secrets, ports) goes in runtime.exs — it is the only config evaluated inside the built release at boot. Putting secrets in config.exs bakes build-time values into the artifact.
  • mix release produces a self-contained tarball with its own ERTS; no Elixir/Erlang needed on the target. Run it with bin/<app> start.
bash
MIX_ENV=prod mix release
_build/prod/rel/my_app/bin/my_app start

mix.exs anatomy, deps, environments, env vars, releases and the umbrella decision live in references/mix-and-releases.md.

Types and modern stdlib

  • Add @spec to public functions. The set-theoretic type system (gradual, sound; v1.18 inferred patterns/calls, v1.19 added protocol + anonymous-fn inference, v1.20 targets full inference) uses them and surfaces warnings at compile time — treat type warnings as bugs, they catch real mismatches before runtime.
  • Use built-in JSON (JSON.encode!/1, JSON.decode!/1, since v1.18) for basic encoding/decoding — no Jason/Poison dependency needed unless you require their extras.
  • mix format is the canonical formatter; run it and gate CI on mix format --check-formatted.
  • mix compile --warnings-as-errors in CI. Dialyzer and Credo are optional add-ons, not required for correct OTP code.
  • v1.19 perf: lazy module loading (>2x faster compiles on large projects) and MIX_OS_DEPS_COMPILE_PARTITION_COUNT for parallel dep compilation.

Anti-patterns

BadWhy it bitesDo instead
String.to_atom(user_input)Atoms are never garbage-collected; attacker-controlled input exhausts the atom table and crashes the VMString.to_existing_atom/1, or keep it a string / map key
One god GenServer all calls route throughSerializes everything into one mailbox — a hard concurrency ceiling and a single point of failureSplit by responsibility; use a Registry of per-entity processes or Task for parallel work
Heavy work inside init/1start_link blocks until init returns, stalling the supervision tree boot{:ok, state, {:continue, msg}} + handle_continue/2
try/rescue wrapping all logicDefeats let-it-crash; the process limps on with corrupt stateValidate at the boundary, trust the path, let the supervisor restart
A new process per trivial callSpawn + mailbox + scheduling overhead for nothingA plain function; processes are for state/concurrency/isolation
Unbounded cast into a slow GenServerProducer outruns consumer, mailbox grows without bound, OOMUse call for backpressure, or a bounded queue / GenStage

Verify

Run scripts/verify.sh from your mix project root (the directory containing mix.exs). It checks mix format --check-formatted and mix compile --warnings-as-errors, and skips cleanly with exit 0 when Elixir/mix is not installed so it never blocks a toolchain-free CI.

© ericrisco, MIT. Rendered from Markdown: HTML in the file is shown as text, images as links, and headings moved down two levels. Raw file

Files

SKILL.md and 5 other files (scripts, references) in skills/elixir of ericrisco/rsc-harness.

  • SKILL.md
  • evals/README.md
  • evals/cases.yaml
  • references/mix-and-releases.md
  • references/otp-patterns.md
  • scripts/verify.sh

Open the folder on GitHubat commit e3d5b33

Compare with similar skills

Elixir next to the 5 skills that share the most tags, products or categories with it. Stars are the repository's; “used in” counts other GitHub owners with a copy.

Elixir compared with similar skills
SkillStarsUsed inTokensAuto-checkLicenceRepo updated
Elixir this skillericrisco/rsc-harness167—~2.9kAutomated safety check: PassMIT
Elixirstreamband/hydra-srt146—~804Automated safety check: PassApache-2.0
Change CleanupSimon-Initiative/oli-torus119—~3.7kAutomated safety check: PassMIT
Elixir AntipatternsGentleman-Programming/Gentleman-Skills657—~2.1kAutomated safety check: PassMIT
Elixir Idiomsirahardianto/awesome-agv157—~771Automated safety check: PassMIT
Refactor React Effectslangfuse/langfuse36k—~1.7kAutomated safety check: PassCustom licence

Similar skills

  • Elixir

    streamband/hydra-srt

    A skill your agent uses for Elixir/Phoenix development in this repo: implementing features, refactors, debugging, tests, Ecto changes, and production-safe fixes.

    146 GitHub stars~804 tokensUpdated 21 days ago
    DevelopmentAuto-check passed
  • Change Cleanup

    Simon-Initiative/oli-torus

    Clean up and harden code introduced by the current branch without drifting into broad refactors.

    119 GitHub stars~3.7k tokensUpdated today
    DevelopmentAuto-check passed
  • Elixir Antipatterns

    Gentleman-Programming/Gentleman-Skills

    Core catalog of 8 critical Elixir/Phoenix anti-patterns covering error handling, separation of concerns, Ecto queries, and testing.

    657 GitHub stars~2.1k tokensUpdated 6 mo ago
    DevelopmentAuto-check passed
  • Elixir Idioms

    irahardianto/awesome-agv

    Elixir and OTP idioms: pattern matching, with pipelines, GenServer and supervision tree architecture, fault-tolerant concurrency, and ExUnit testing.

    157 GitHub stars~771 tokensUpdated 3 days ago
    DevelopmentAuto-check passed
  • Refactor React Effects

    langfuse/langfuse

    Refactor avoidable React useEffect usage in Langfuse frontend code.

    36k GitHub stars~1.7k tokensUpdated today
    DevelopmentAuto-check passed
  • Investigate

    oliver-kriska/claude-elixir-phoenix

    Find the root cause of Elixir/Phoenix bugs — crashes, exceptions, stack traces, compile errors, LiveView that won't update, silent failures.

    565 GitHub stars~1.4k tokensUpdated 2 days ago
    DevelopmentAuto-check passed

More from ericrisco/rsc-harness

All 227 skills in this repo
  • Ab Testing

    ericrisco/rsc-harness

    A skill your agent uses when designing or analyzing a controlled experiment — falsifiable hypothesis, sample size from an MDE, reading significance/CI/power, CUPED, or rescuing tests that won't go…

    167 GitHub stars~2.4k tokensUpdated today
    Auto-check passed
  • Accessibility

    ericrisco/rsc-harness

    A skill your agent uses when making a web UI conform to WCAG 2.2 Level AA — axe-core or Lighthouse a11y violations, keyboard operability, focus management, ARIA roles/names/live regions, contrast…

    167 GitHub stars~3.4k tokensUpdated today
    Auto-check passed
  • Ads

    ericrisco/rsc-harness

    A skill your agent uses when running or fixing paid acquisition on Google or Meta — campaign structure (Performance Max, Demand Gen, Search, Advantage+), platform-fit creative, budget/scaling rules…

    167 GitHub stars~2.2k tokensUpdated today
    Auto-check passed
  • Agent Eval

    ericrisco/rsc-harness

    A skill your agent uses when measuring whether an LLM or agent system actually got better and gating merges on it: golden sets, fixing an inflated LLM-as-judge, scoring RAG (faithfulness, contextual…

    167 GitHub stars~3.2k tokensUpdated today
    Auto-check passed
  • AI Media

    ericrisco/rsc-harness

    A skill your agent uses when a creative goal must become a finished media file: pick and order generative-media models per modality — AI voiceover, image-to-video clips, score — then glue them with…

    167 GitHub stars~3.3k tokensUpdated today
    Auto-check passed
  • Analytics

    ericrisco/rsc-harness

    A skill your agent uses when instrumenting product or web analytics — GA4/PostHog SDK wiring, event taxonomy, funnels, double-counted events, consent gating, PII scrubbing.

    167 GitHub stars~2.8k tokensUpdated today
    Auto-check passed

Works with

Questions about Elixir

What does Elixir do?

A skill your agent uses when writing or refactoring Elixir/OTP on the BEAM — GenServers, supervision trees and restart strategies, pattern matching, mix projects and releases — or when processes…. Elixir is an agent skill from ericrisco/rsc-harness. Use when writing or refactoring Elixir/OTP on the BEAM — GenServers, supervision trees and restart strategies, pattern matching, mix projects and releases — or when processes misbehave (restart loops, mailbox growth, call timeouts).

When should I use Elixir?

Elixir fits situations like: refactoring Elixir/OTP on the BEAM — GenServers; supervision trees and restart strategies; pattern matching; mix projects and releases —.

How do I install Elixir in Claude Code?

Run `npx skills add ericrisco/rsc-harness --skill elixir -a claude-code`. Or copy the skill folder (skills/elixir in ericrisco/rsc-harness) into .claude/skills/elixir in your project. Claude Code loads it when a task matches its description.

How do I install Elixir in Codex?

Run `npx skills add ericrisco/rsc-harness --skill elixir -a codex`. Or copy the skill folder (skills/elixir in ericrisco/rsc-harness) into .agents/skills/elixir in your project. Codex loads it when a task matches its description.

Can I use Elixir in Cursor, Gemini CLI or GitHub Copilot?

Cursor, Gemini CLI, GitHub Copilot and OpenCode also load SKILL.md folders. With the skills CLI, run `npx skills add ericrisco/rsc-harness --skill elixir -a cursor` (or -a gemini-cli, github-copilot or opencode for the others). To copy it by hand, put the folder in .cursor/skills/elixir, .gemini/skills/elixir, .github/skills/elixir and .opencode/skills/elixir in your project.

What does Elixir need to run?

Going by SKILL.md and its folder, Elixir needs a shell for the scripts in its folder. Our summary lists: A Bash shell; Docker.

Does Elixir access the network?

SKILL.md contains no URLs. Any network use would come from the scripts or tools the agent runs. This is read from the text; nothing was executed.

Is Elixir safe to install?

Our automated static check of SKILL.md found no risky patterns, such as piping downloads into a shell, reading credential files or hidden Unicode. It is not a guarantee. The check reads SKILL.md only: the scripts in the folder are not scanned, so read them before running anything.

What licence does Elixir use?

Elixir is published under the MIT licence (the repository's licence). It allows redistribution, so the full SKILL.md is shown on this page.

How many tokens does Elixir use?

About 2.9k tokens (SKILL.md is roughly 12k characters). Agents keep only the skill's name and description in context until a task matches; then they load SKILL.md in full. Its references folder adds about 1.8k tokens, read only when the agent opens those files.

What are the alternatives to Elixir?

Skills that share tags, products or a category with Elixir: Elixir (streamband/hydra-srt, 146 stars), Change Cleanup (Simon-Initiative/oli-torus, 119 stars), Elixir Antipatterns (Gentleman-Programming/Gentleman-Skills, 657 stars) and Elixir Idioms (irahardianto/awesome-agv, 157 stars). The comparison table on this page puts their stars, adoption, token cost, safety result and licence side by side.

Who maintains Elixir?

ericrisco (a GitHub user) maintains it in ericrisco/rsc-harness, which has 167 GitHub stars. The repository holds 227 skills in this directory. The repository was last updated on October 7, 2026.

Source: ericrisco/rsc-harness on GitHub. Facts on this page come from the repository at the commit we read; the author's words are quoted as theirs.