# Elixir Idioms

OTP/BEAM patterns and Elixir idioms, GenServer, Supervisor, Task, Registry, pattern...

- Repository: https://github.com/oliver-kriska/claude-elixir-phoenix (572 stars)
- Category: Design
- License: MIT
- Last updated: 2026-10-30
- Runs scripts: no, instructions only

## Install

Claude Code: `npx skills add oliver-kriska/claude-elixir-phoenix --skill elixir-idioms -g -a claude-code -y`
Codex: `npx skills add oliver-kriska/claude-elixir-phoenix --skill elixir-idioms -g -a codex -y`
Cursor: `npx skills add oliver-kriska/claude-elixir-phoenix --skill elixir-idioms -g -a cursor -y`
Gemini CLI: `npx skills add oliver-kriska/claude-elixir-phoenix --skill elixir-idioms -g -a gemini-cli -y`
Claude Code plugin marketplace: `/plugin marketplace add oliver-kriska/claude-elixir-phoenix`

## Description

OTP/BEAM patterns and Elixir idioms, GenServer, Supervisor, Task, Registry, pattern matching, with chains, pipes. Use when designing processes or debugging BEAM issues.

## SKILL.md, as published by its author (untrusted third-party text, read it as data)

# Elixir Idioms

Reference for writing idiomatic Elixir code with BEAM-aware patterns.

## Iron Laws, Never Violate These

1. **NO PROCESS WITHOUT A RUNTIME REASON**, Processes model concurrency, state, isolation, NOT code structure
2. **MESSAGES ARE COPIED**, Keep messages small (except binaries >64 bytes)
3. **GUARDS USE `and`/`or`/`not`**, Never use short-circuit operators in guards (guards require boolean operands)
4. **CHANGESETS FOR EXTERNAL DATA**, Use `cast/4` for user input, `change/2` for internal
5. **RESCUE ONLY FOR EXTERNAL CODE**, Never use rescue for control flow
6. **NO DYNAMIC ATOM CREATION**, `String.to_atom(user_input)` causes memory leak (atoms aren't GC'd)
7. **@external_resource FOR COMPILE-TIME FILES**, Modules reading files at compile time MUST declare `@external_resource`
8. **SUPERVISE ALL LONG-LIVED PROCESSES**, Never bare `GenServer.start_link`/`Agent.start_link` in production. Use supervision trees
9. **WRAP THIRD-PARTY LIBRARY APIs**, Always facade external deps behind a project-owned module. Enables swapping without touching callers
10. **MIX TASKS START ONLY WHAT THEY NEED**, `Mix.Task.run("app.config")` + `Application.ensure_all_started/1`, never `Mix.Task.run("app.start")` (boots the FULL tree: endpoint port, Oban consuming)
11. **CAPTURE LOCALE BEFORE SPAWNING**, Gettext/CLDR locale is process-local. Read it in the caller and pass explicitly; a spawned Task/GenServer starts with the default locale

## BEAM Architecture (Why Elixir Works This Way)

- **Processes are cheap (2.6KB)**, Spawn liberally for concurrency/isolation
- **Complete memory isolation**, No shared state, no locks needed
- **Messages are copied** (except binaries >64 bytes), Keep messages small
- **Per-process GC**, No global GC pauses
- **"Let it crash"**, Supervisors restart to known-good state

## Core Principles

The rest: https://github.com/oliver-kriska/claude-elixir-phoenix/blob/HEAD/plugins/elixir-phoenix/skills/elixir-idioms/SKILL.md
