> elixir
You are an expert in Elixir, the functional programming language built on the Erlang VM (BEAM). You help developers build highly concurrent, fault-tolerant, and distributed systems using Elixir's process model, pattern matching, GenServer, supervision trees, Phoenix web framework, LiveView for real-time UI, and Ecto for database interactions — achieving massive concurrency with lightweight processes and "let it crash" reliability.
curl "https://skillshub.wtf/TerminalSkills/skills/elixir?format=md"Elixir — Functional Language for Scalable Applications
You are an expert in Elixir, the functional programming language built on the Erlang VM (BEAM). You help developers build highly concurrent, fault-tolerant, and distributed systems using Elixir's process model, pattern matching, GenServer, supervision trees, Phoenix web framework, LiveView for real-time UI, and Ecto for database interactions — achieving massive concurrency with lightweight processes and "let it crash" reliability.
Core Capabilities
Language Basics
# Pattern matching
{:ok, user} = fetch_user(id)
%{name: name, email: email} = user
# Pipeline operator (chain transformations)
result =
data
|> Enum.filter(&(&1.active))
|> Enum.map(&transform/1)
|> Enum.sort_by(& &1.score, :desc)
|> Enum.take(10)
# Modules and functions
defmodule MyApp.Accounts do
def create_user(attrs) do
%User{}
|> User.changeset(attrs)
|> Repo.insert()
end
def authenticate(email, password) do
with {:ok, user} <- get_user_by_email(email),
true <- Bcrypt.verify_pass(password, user.password_hash) do
{:ok, user}
else
_ -> {:error, :invalid_credentials}
end
end
end
GenServer (Stateful Processes)
defmodule MyApp.RateLimiter do
use GenServer
# Client API
def start_link(opts) do
GenServer.start_link(__MODULE__, opts, name: __MODULE__)
end
def check_rate(user_id, limit \\ 100) do
GenServer.call(__MODULE__, {:check, user_id, limit})
end
# Server callbacks
@impl true
def init(_opts) do
schedule_cleanup()
{:ok, %{}} # Initial state: empty map
end
@impl true
def handle_call({:check, user_id, limit}, _from, state) do
now = System.monotonic_time(:second)
requests = Map.get(state, user_id, [])
recent = Enum.filter(requests, &(&1 > now - 60))
if length(recent) < limit do
{:reply, :ok, Map.put(state, user_id, [now | recent])}
else
{:reply, {:error, :rate_limited}, state}
end
end
@impl true
def handle_info(:cleanup, state) do
now = System.monotonic_time(:second)
cleaned = Map.new(state, fn {k, v} ->
{k, Enum.filter(v, &(&1 > now - 60))}
end)
schedule_cleanup()
{:noreply, cleaned}
end
defp schedule_cleanup, do: Process.send_after(self(), :cleanup, 60_000)
end
Phoenix LiveView (Real-Time UI)
defmodule MyAppWeb.DashboardLive do
use MyAppWeb, :live_view
@impl true
def mount(_params, session, socket) do
if connected?(socket) do
MyApp.PubSub.subscribe("metrics")
:timer.send_interval(5000, :tick)
end
{:ok, assign(socket,
users_online: 0,
orders_today: 0,
revenue: Decimal.new(0)
)}
end
@impl true
def handle_info(:tick, socket) do
{:noreply, assign(socket,
users_online: MyApp.Presence.count(),
orders_today: MyApp.Orders.count_today(),
revenue: MyApp.Orders.revenue_today()
)}
end
@impl true
def handle_info({:new_order, order}, socket) do
{:noreply, update(socket, :orders_today, &(&1 + 1))
|> update(:revenue, &Decimal.add(&1, order.total))}
end
@impl true
def render(assigns) do
~H"""
<div class="grid grid-cols-3 gap-4">
<.stat_card title="Users Online" value={@users_online} />
<.stat_card title="Orders Today" value={@orders_today} />
<.stat_card title="Revenue" value={"$#{@revenue}"} />
</div>
"""
end
end
Supervision Trees
defmodule MyApp.Application do
use Application
def start(_type, _args) do
children = [
MyApp.Repo, # Database (auto-restarts on crash)
{Phoenix.PubSub, name: MyApp.PubSub},
MyApp.RateLimiter, # Custom GenServer
MyAppWeb.Endpoint, # Web server
{Task.Supervisor, name: MyApp.TaskSupervisor},
]
opts = [strategy: :one_for_one, name: MyApp.Supervisor]
Supervisor.start_link(children, opts)
# If any child crashes, only that child restarts (one_for_one)
end
end
Installation
# Install Elixir
brew install elixir # macOS
# Or: https://elixir-lang.org/install.html
# New Phoenix project
mix phx.new my_app
cd my_app && mix deps.get
mix ecto.create && mix phx.server
Best Practices
- Let it crash — Don't over-handle errors; use supervisors to restart failed processes automatically
- Pattern matching — Match on function arguments and return values; avoid if/else chains
- Pipeline operator — Chain transformations with
|>; reads top-to-bottom like a data pipeline - GenServer for state — Use GenServer for in-memory state, rate limiters, caches; supervised and fault-tolerant
- LiveView over SPAs — Use Phoenix LiveView for real-time UI; no JavaScript framework needed, server-rendered
- Ecto changesets — Validate and cast data through changesets; never trust raw input
- PubSub for events — Use Phoenix.PubSub for inter-process communication; scales across nodes
- Telemetry for observability — Attach to
:telemetryevents for metrics; Ecto, Phoenix emit events automatically
> related_skills --same-repo
> zustand
You are an expert in Zustand, the small, fast, and scalable state management library for React. You help developers manage global state without boilerplate using Zustand's hook-based stores, selectors for performance, middleware (persist, devtools, immer), computed values, and async actions — replacing Redux complexity with a simple, un-opinionated API in under 1KB.
> zoho
Integrate and automate Zoho products. Use when a user asks to work with Zoho CRM, Zoho Books, Zoho Desk, Zoho Projects, Zoho Mail, or Zoho Creator, build custom integrations via Zoho APIs, automate workflows with Deluge scripting, sync data between Zoho apps and external systems, manage leads and deals, automate invoicing, build custom Zoho Creator apps, set up webhooks, or manage Zoho organization settings. Covers Zoho CRM, Books, Desk, Projects, Creator, and cross-product integrations.
> zod
You are an expert in Zod, the TypeScript-first schema declaration and validation library. You help developers define schemas that validate data at runtime AND infer TypeScript types at compile time — eliminating the need to write types and validators separately. Used for API input validation, form validation, environment variables, config files, and any data boundary.
> zipkin
Deploy and configure Zipkin for distributed tracing and request flow visualization. Use when a user needs to set up trace collection, instrument Java/Spring or other services with Zipkin, analyze service dependencies, or configure storage backends for trace data.