Skip to content
Skillpedia
General coding48k · #4277

elixir

Makes your agent generate concise and correct Elixir code. This is great for building scalable and fault-tolerant systems.

What it does

This guide teaches how to write more efficient and clear code in the Elixir programming language. It shows better ways to organize code, handle errors, and use language features.

When to use it

  • ✓When learning Elixir and wanting to write high-quality code.
  • ✓When reviewing Elixir code to make it more readable.
  • ✓When struggling to write Elixir code idiomatically.

Example of what to ask your AI

“How can I write a function that checks if a number is even more efficiently in Elixir?”

Want more? Open the sections below.

How to use

The easiest way: copy the message below and paste it into Claude, ChatGPT, Cursor or any AI. It reads the skill and follows the instructions.

Skill link

https://github.com/sickn33/agentic-awesome-skills/blob/main/plugins/agentic-awesome-skills-claude/skills/super-code/elixir/SKILL.md

Ready-to-paste message

Use this skill to help me: https://github.com/sickn33/agentic-awesome-skills/blob/main/plugins/agentic-awesome-skills-claude/skills/super-code/elixir/SKILL.md Read the SKILL.md file at that link and follow its instructions for my task.
How it works

The guide compares common approaches with code examples, showing how to use features like 'pattern matching' and the 'pipe' operator to simplify logic and avoid errors.

Installation

Easiest way: copy the skill link and paste it into Claude, ChatGPT or Cursor asking it to follow the instructions.

In the terminal (Claude Code, Codex, Cursor), in your project folder:

npx skills add sickn33/agentic-awesome-skills --skill elixir

Or download just the file:

curl -L https://raw.githubusercontent.com/sickn33/agentic-awesome-skills/main/plugins/agentic-awesome-skills-claude/skills/super-code/elixir/SKILL.md -o SKILL.md
Technical content (original SKILL.md)

Original text by the author, straight from GitHub.

Elixir / Erlang: Idiomatic Efficiency Reference

When to Use

  • Use this skill when the task matches this description: Language-specific super-code guidelines for elixir.

Table of Contents

  1. Pattern Matching & Guards
  2. Pipe Operator & Transforms
  3. Processes & OTP
  4. Error Handling
  5. Collections & Enum
  6. Structs & Protocols
  7. Anti-patterns specific to Elixir/Erlang

1. Pattern Matching & Guards {#patterns}

# ❌ Extracting with Map.get then checking
value = Map.get(map, :key)
if value != nil do
  process(value)
end

# ✅ — pattern match directly
case map do
  %{key: value} -> process(value)
  _ -> :noop
end
# or with if:
if value = map[:key], do: process(value)
# ❌ Nested case for multiple conditions
case fetch_user(id) do
  {:ok, user} ->
    case validate(user) do
      {:ok, valid_user} -> save(valid_user)
      {:error, reason} -> {:error, reason}
    end
  {:error, reason} -> {:error, reason}
end

# ✅ — with clause
with {:ok, user} <- fetch_user(id),
     {:ok, valid_user} <- validate(user) do
  save(valid_user)
end
# ❌ if/else for known shapes
def area(shape) do
  if shape.type == :circle do
    :math.pi() * shape.radius * shape.radius
  else
    shape.width * shape.height
  end
end

# ✅ — multi-clause function with pattern match
def area(%{type: :circle, radius: r}), do: :math.pi() * r * r
def area(%{type: :rect, width: w, height: h}), do: w * h
# ❌ Checking type at runtime
def process(x) do
  if is_integer(x) and x > 0 do
    x * 2
  end
end

# ✅ — guard clause
def process(x) when is_integer(x) and x > 0, do: x * 2
def process(_), do: {:error, :invalid_input}

2. Pipe Operator & Transforms {#pipes}

# ❌ Nested function calls
String.trim(String.downcase(String.replace(input, ~r/\s+/, " ")))

# ✅
input
|> String.replace(~r/\s+/, " ")
|> String.downcase()
|> String.trim()
# ❌ Pipe into anonymous function awkwardly
data
|> (fn x -> x * 2 end).()

# ✅ — use then/1 or named function
data
|> then(&(&1 * 2))
# or better: extract a named function
data |> double()
# ❌ Single-step pipe (no gain in readability)
result = list |> Enum.count()

# ✅ — direct call for single operation
result = Enum.count(list)

Pipe when 2+ transforms. Direct call for single operation. First arg flows through pipe.


3. Processes & OTP {#otp}

# ❌ Raw spawn for stateful process
pid = spawn(fn -> loop(%{count: 0}) end)
send(pid, {:increment})

# ✅ — GenServer for stateful processes
defmodule Counter do
  use GenServer

  def start_link(init \\ 0), do: GenServer.start_link(__MODULE__, init)
  def increment(pid), do: GenServer.call(pid, :increment)

  @impl true
  def init(count), do: {:ok, count}

  @impl true
  def handle_call(:increment, _from, count), do: {:reply, count + 1, count + 1}
end
# ❌ Spawning without linking (orphan process on crash)
spawn(fn -> do_work() end)

# ✅ — Task for fire-and-forget with supervision
Task.start(fn -> do_work() end)
# or for awaitable result:
task = Task.async(fn -> do_work() end)
result = Task.await(task)
# ❌ Manual process registry
Process.register(self(), :my_worker)

# ✅ — use Registry or named GenServer
{:ok, _} = Registry.start_link(keys: :unique, name: MyRegistry)
GenServer.start_link(Worker, arg, name: {:via, Registry, {MyRegistry, :my_worker}})
# ❌ try/catch in GenServer (breaks supervision)
def handle_call(:work, _from, state) do
  try do
    result = risky_operation()
    {:reply, result, state}
  catch
    _ -> {:reply, :error, state}
  end
end

# ✅ — let it crash; supervisor restarts
def handle_call(:work, _from, state) do
  result = risky_operation()
  {:reply, result, state}
end

"Let it crash" — supervisors handle recovery. Don't defensively catch inside GenServers.


4. Error Handling {#errors}

# ❌ Raising for expected failures
def find_user(id) do
  case Repo.get(User, id) do
    nil -> raise "User not found"
    user -> user
  end
end

# ✅ — tagged tuples for expected outcomes
def find_user(id) do
  case Repo.get(User, id) do
    nil -> {:error, :not_found}
    user -> {:ok, user}
  end
end
# ❌ Ignoring error tuple
{:ok, result} = might_fail()  # crashes on {:error, _}

# ✅ — handle both cases
case might_fail() do
  {:ok, result} -> process(result)

…
FAQ

What is 'pattern matching'?

It's a way to elegantly check and extract data from code structures, like checking if a map has a specific key and getting its value at the same time.

What is the 'pipe' operator (`|>`)?

It allows chaining function calls readably, passing the result of one function as an argument to the next, from top to bottom.

What does 'Let it crash' mean?

It's a philosophy in Elixir where, instead of trying to catch every possible error, you let the program fail in a controlled way, and a supervision system restarts the necessary parts.

Details

Original description by the author

Language-specific super-code guidelines for elixir.

repo: sickn33/agentic-awesome-skills

Popularity

GitHub stars
48k
Ranking position
#4277
License
MIT
Updated
10/15/2026

Is this skill useful?

0

Sign in to vote.

Comments

  • …

More skills from this repository

Similar skills