🎯

elixir-patterns

🎯Skill

from j-morgan6/elixir-claude-optimization

VibeIndex|
What it does

Guides developers through Elixir's idiomatic coding patterns, focusing on pattern matching, pipe operators, immutability, and functional programming best practices.

πŸ“¦

Part of

j-morgan6/elixir-claude-optimization(7 items)

elixir-patterns

Installation

Add MarketplaceAdd marketplace to Claude Code
/plugin marketplace add j-morgan6/elixir-claude-optimization
Install PluginInstall plugin from marketplace
/plugin install elixir-optimization --scope user
Claude CodeAdd plugin in Claude Code
/plugin list
Install ScriptRun install script
curl -sL https://raw.githubusercontent.com/j-morgan6/elixir-claude-optimization/main/install.sh | bash
git cloneClone repository
git clone https://github.com/j-morgan6/elixir-claude-optimization.git
πŸ“– Extracted from docs: j-morgan6/elixir-claude-optimization
3Installs
-
AddedFeb 4, 2026

Skill Details

SKILL.md

Use when writing Elixir code. Covers pattern matching, pipe operators, with statements, guards, list comprehensions, and Elixir naming conventions.

Overview

# Elixir Patterns and Conventions

Pattern Matching

Pattern matching is the primary control flow mechanism in Elixir. Prefer it over conditional statements.

Prefer Pattern Matching Over if/else

Bad:

```elixir

def process(result) do

if result.status == :ok do

result.data

else

nil

end

end

```

Good:

```elixir

def process(%{status: :ok, data: data}), do: data

def process(_), do: nil

```

Use Case for Multiple Patterns

Bad:

```elixir

def handle_response(response) do

if response.status == 200 do

{:ok, response.body}

else if response.status == 404 do

{:error, :not_found}

else

{:error, :unknown}

end

end

```

Good:

```elixir

def handle_response(%{status: 200, body: body}), do: {:ok, body}

def handle_response(%{status: 404}), do: {:error, :not_found}

def handle_response(_), do: {:error, :unknown}

```

Pipe Operator

Use the pipe operator |> to chain function calls for improved readability.

Basic Piping

Bad:

```elixir

String.upcase(String.trim(user_input))

```

Good:

```elixir

user_input

|> String.trim()

|> String.upcase()

```

Pipe into Function Heads

Bad:

```elixir

def process_user(user) do

validated = validate_user(user)

transformed = transform_user(validated)

save_user(transformed)

end

```

Good:

```elixir

def process_user(user) do

user

|> validate_user()

|> transform_user()

|> save_user()

end

```

With Statement

Use with for sequential operations that can fail.

Bad:

```elixir

def create_post(params) do

case validate_params(params) do

{:ok, valid_params} ->

case create_changeset(valid_params) do

{:ok, changeset} ->

Repo.insert(changeset)

error -> error

end

error -> error

end

end

```

Good:

```elixir

def create_post(params) do

with {:ok, valid_params} <- validate_params(params),

{:ok, changeset} <- create_changeset(valid_params),

{:ok, post} <- Repo.insert(changeset) do

{:ok, post}

end

end

```

Immutability

All data structures are immutable. Functions return new values rather than modifying in place.

```elixir

# Always returns a new list

list = [1, 2, 3]

new_list = [0 | list] # [0, 1, 2, 3]

# list is still [1, 2, 3]

```

Guards

Use guards for simple type and value checks in function heads.

```elixir

def calculate(x) when is_integer(x) and x > 0 do

x * 2

end

def calculate(_), do: {:error, :invalid_input}

```

Anonymous Functions

Use the capture operator & for concise anonymous functions.

Verbose:

```elixir

Enum.map(list, fn x -> x * 2 end)

```

Concise:

```elixir

Enum.map(list, &(&1 * 2))

```

Named function capture:

```elixir

Enum.map(users, &User.format/1)

```

List Comprehensions

Use for comprehensions for complex transformations and filtering.

Bad (multiple passes):

```elixir

list

|> Enum.map(&transform/1)

|> Enum.filter(&valid?/1)

|> Enum.map(&format/1)

```

Good (single pass):

```elixir

for item <- list,

transformed = transform(item),

valid?(transformed) do

format(transformed)

end

```

Naming Conventions

  • Module names: PascalCase
  • Function names: snake_case
  • Variables: snake_case
  • Atoms: :snake_case
  • Predicate functions end with ?: valid?, empty?
  • Dangerous functions end with !: save!, update!

Boolean Checks

Functions returning booleans should end with ?.

```elixir

def admin?(user), do: user.role == :admin

def empty?(list), do: list == []

```

Error Tuples

Return {:ok, result} or {:error, reason} tuples for operations that can fail.

```elixir

def fetch_user(id) do

case Repo.get(User, id) do

nil -> {:error, :not_found}

user -> {:ok, user}

end

end

```

Documentation

Use @doc for public functions and @moduledoc for modules.

```elixir

defmodule MyModule do

@moduledoc """

This module handles user operations.

"""

@doc """

Fetches a user by ID.

Returns {:ok, user} or {:error, :not_found}.

"""

def fetch_user(id), do: # ...

end

```