OTP Thinking for Elixir
Introduction
OTP Thinking is a specialized skill for Claude Code designed to guide developers through the nuances of the Erlang/Elixir Open Telecom Platform (OTP). While many developers are familiar with basic syntax, mastering concurrency, fault tolerance, and state management requires a paradigm shift.
This skill helps you navigate complex architectural decisions, such as when to use a GenServer versus a simple Task, or choosing between Oban and Broadway for background processing. By integrating this skill, Claude becomes an expert architect capable of auditing your supervision trees and identifying potential throughput bottlenecks before they reach production.
Key Features:
- Architectural Guardrails: Prevents common anti-patterns like wrapping stateless functions in
GenServer. - Concurrency Logic: Expert advice on
Task.Supervisorusage andasync_nolinkpatterns. - Process Management: Guidance on
DynamicSupervisor,Registry, andPartitionSupervisorfor scaling to millions of processes. - Job Processing: Clear decision frameworks for choosing between Oban (persistence) and Broadway (ingestion).
- Debugging & Observability: Quick access to
:systracing andTelemetryintegration patterns.
Installation
To add the OTP Thinking skill to your Claude Code environment, ensure you have the claude-code-elixir repository cloned or the specific skill file available in your configuration path.
-
Clone the repository:
Terminal window git clone https://github.com/georgeguimaraes/claude-code-elixir.git -
Add to Claude Code: Copy the
otp-thinkingskill definition into your Claude Code skills directory (typically.claudecode/skills/or as defined in your local setup). -
Verify: Ask Claude: “What are the rules for using GenServers?” to trigger the skill logic.
Usage
This skill is automatically triggered when you discuss Elixir concurrency, background jobs, or system design. You can also explicitly invoke its logic with specific prompts:
Example Prompts:
- “I need to cache this data in memory. Should I use a GenServer or ETS?”
- “How do I handle concurrent requests without creating a bottleneck?”
- “Review my supervision tree: I’m using
:one_for_allbut I’m worried about restart loops.” - “Should I use Oban or Broadway for processing SQS messages?”
The Iron Law of OTP
GENSERVER IS A BOTTLENECK BY DESIGN
A
GenServerprocesses exactly one message at a time. This skill enforces a “read-bypass” pattern: useGenServerfor serialized writes and ETS with:read_concurrencyfor high-throughput reads.
Abstraction Decision Tree
When you ask Claude how to structure a feature, it uses the following logic provided by this skill:
- Need State?
- No → Use a Plain Function.
- Yes → Is it complex behavior?
- No → Use an Agent.
- Yes → Need Supervision?
- No → Use
spawn_link. - Yes → Is it Request/Response?
- No → Use
Task.Supervisor. - Yes → Explicit States?
- No →
GenServer. - Yes →
GenStateMachine.
- No →
- No → Use
- No → Use
Storage & Persistence
The skill provides instant documentation for Elixir storage options:
| Need | Recommended Tool |
|---|---|
| Memory Cache | ETS (fast reads/writes) |
| Static Config | :persistent_term (optimized for reads) |
| Disk Persistence | DETS (simple, 2GB limit) |
| Distributed Transactions | Mnesia |
Debugging Tips
If your system is behaving unexpectedly, you can ask Claude to provide :sys debugging commands:
:sys.get_state(pid) # Inspect current state:sys.trace(pid, true) # Trace process eventsNote: Always remember to turn off tracing when finished to avoid performance degradation.