elixir-conventions
Coding style and convention reference for maintainable Elixir projects.
Install
mkdir -p .claude/skills/elixir-conventions && curl -L -o skill.zip "https://agentskills.codes/api/skills/download/14723" && unzip -o skill.zip -d .claude/skills/elixir-conventions && rm skill.zipInstalls to .claude/skills/elixir-conventions
Activation
This is the description your AI agent reads to decide when to run this skill — the better it matches your request, the more reliably it fires.
Elixir-specific coding patterns and conventions.Key capabilities
- →Prefer `with` chains over nested `case` for control flow.
- →Use `typedstruct` for struct definitions.
- →Organize GenServer modules into clear sections.
- →Choose state location based on queryability and crash tolerance.
- →Start `@moduledoc` with a one-sentence purpose.
- →Define examples with the `example` macro for caching and composition.
How it works
This skill provides guidelines for writing Elixir code, covering control flow, type definitions, GenServer organization, state management, and documentation practices. It also details how to use the `ExExample` library for creating cached and composable examples.
Inputs & outputs
When to use elixir-conventions
- →Refactoring Elixir control flow
- →Structuring GenServer modules
- →Defining standard Elixir types
About this skill
Elixir Conventions
Control Flow
- Prefer
withchains over nestedcase. - Use
Enum.reduce_whileorEnum.flat_mapoverEnum.reducewith internal conditionals. - Pattern match in function heads rather than branching in the body.
Types & Structs
- Use
typedstructfor struct definitions. - Prefer union types for option lists over keyword defaults:
@type startup_options :: {:name, atom()} | {:timeout, pos_integer()} @spec start_link(list(startup_options())) :: GenServer.on_start() - Keep type definitions near the top, after
use/aliasblocks.
GenServer
handle_callbody:{:reply, do_foo(...), state}— core logic in thedo_function.- Never call a callback from another callback.
- Organize GenServer modules into clear sections:
############################################################ # Public API # ############################################################ ############################################################ # GenServer Callbacks # ############################################################ ############################################################ # Private Implementation # ############################################################
State Boundaries
Choose where state lives based on two questions:
- Should users or external code be able to query it? If yes → persistent storage (DB on disk).
- Can we tolerate losing it on crash or shutdown? If yes → process state is fine for pure implementation details. If we can tolerate loss on shutdown but not on crash → an ETS/Mnesia table (survives process crashes, lost on VM stop) may be the right middle ground.
Documentation
- First-person voice: "I am the X module." / "I return the Y."
@moduledocstarts with one-sentence purpose.### Public APIsection listing all public functions.- All public functions need
@docand@spec.
Examples
Examples use the ExExample library for caching and composition.
use ExExamplein the module,import ExUnit.Assertionsfor assertions.- Define examples with the
examplemacro:@spec create_upload() :: Upload.t() example create_upload do {:ok, upload} = Uploads.store_new_file(...) assert upload.stored_name != nil upload # return a useful object end - Examples are cached — calling one from another reuses the
result instead of re-running. This enables composition:
example add_comment do upload = EUpload.create_upload() # cached, not re-run {:ok, comment} = Comments.create(...) comment end - Override
rerun?/1to control caching per example:def rerun?(_), do: trueto always re-run (e.g., examples that spawn processes or depend on runtime state). Pattern match on specific examples for selective control. - Tests:
use ExExample.ExUnit, for: Examples.EModuleto auto-generate one test per example. - Live in
lib/examples/e_<module>.ex. - Module name:
E<Module>(e.g.,EUpload,EEventStore). - Every example gets
@spec— they are typed public functions. - Run with:
mix run -e 'EModule.example_name()' - Build examples incrementally: verify each layer in IEX before writing the next. The examples ARE the verification.
Interactive Testing
- Run one-off expressions:
timeout 60 mix run -e 'code'(never use--no-halt, it hangs the VM). - Inspect process state:
:sys.get_state(pid)
Formatting
- 98 character line length.
- Run
mix formatbefore finalizing. - Section headers use banner comments:
############################################################ # Section Name # ############################################################
When not to use it
- →When documentation is not needed.
- →When state management is not a concern.
- →When GenServer modules are not used.
Limitations
- →The skill is specific to Elixir coding practices.
- →The `ExExample` library is used for examples.
- →State boundary decisions are based on queryability and crash tolerance.
How it compares
This approach offers specific Elixir-centric guidelines and tools like `ExExample` for structured code and examples, unlike generic coding advice.
Compared to similar skills
elixir-conventions side by side with the closest alternatives in the catalog.
| Skill | Installs | Updated | Safety | Difficulty |
|---|---|---|---|---|
| elixir-conventions (this skill) | 0 | 5mo | No flags | Intermediate |
| salesforce-development | 14 | 6mo | No flags | Advanced |
| woocommerce-code-review | 6 | 3mo | No flags | Intermediate |
| woocommerce-backend-dev | 7 | 3mo | No flags | Intermediate |
Try saying
Example prompts that trigger this skill in your AI assistant.
You might also like
salesforce-development
davila7
Expert patterns for Salesforce platform development including Lightning Web Components (LWC), Apex triggers and classes, REST/Bulk APIs, Connected Apps, and Salesforce DX with scratch orgs and 2nd generation packages (2GP). Use when: salesforce, sfdc, apex, lwc, lightning web components.
woocommerce-code-review
woocommerce
Review WooCommerce code changes for coding standards compliance. Use when reviewing code locally, performing automated PR reviews, or checking code quality.
woocommerce-backend-dev
woocommerce
Add or modify WooCommerce backend PHP code following project conventions. Use when creating new classes, methods, hooks, or modifying existing backend code. **MUST be invoked before writing any PHP unit tests.**
woocommerce-dev-cycle
woocommerce
Run tests, linting, and quality checks for WooCommerce development. Use when running tests, fixing code style, or following the development workflow.
golang
MadAppGang
Use when building Go backend services, implementing goroutines/channels, handling errors idiomatically, writing tests with testify, or following Go best practices for APIs/CLI tools.
convex-best-practices
waynesutton
Guidelines for building production-ready Convex apps covering function organization, query patterns, validation, TypeScript usage, error handling, and the Zen of Convex design philosophy