Curated library of 38 atomic skills, 7 personas, and 1 orchestrator for Elixir and Phoenix development. Organized by category: fundamentals, phoenix, database, testing, auth, infrastructure, quality, security, integrations, tooling, frameworks, personas, and orchestration. Covers core Elixir patterns, Phoenix LiveView, Ecto, OTP, Oban, testing, security, deployment, real-time, and modern tooling (Req, Swoosh, Cachex, Broadway, Ash).
73
91%
Does it follow best practices?
Impact
—
No eval scenarios have been run
Advisory
Suggest reviewing before use
mix credo gen.config first — never hand-craft .credo.exs from scratch--strict in CI — enables additional checks that are disabled by defaultlib/credo/checks/ — never inline them in application codeFollow this sequence when setting up or customizing Credo:
# mix.exs
defp deps do
[
{:credo, "~> 1.7", only: [:dev, :test], runtime: false}
]
endmix deps.getmix credo gen.config.credo.exsEdit the generated file to match your project's needs. See Basic Configuration below.
mix credoSuccess: Credo exits 0 and prints a summary with issue counts per category. If issues are found, review them — fix violations, adjust check configuration, or add inline disable comments for intentional exceptions.
mix credo --strictStrict mode enables additional checks disabled by default (mostly design-related). CI must use --strict.
See CI Integration below.
For project-specific patterns, add custom check modules to lib/credo/checks/. See Custom Checks below.
Use
mix credo gen.configfor the complete check list rather than writing it by hand.
# .credo.exs
%{
configs: [
%{
name: "default",
strict: false,
color: true,
files: %{
included: ["lib/", "src/", "test/", "web/", "apps/"],
excluded: [~r"/_build/", ~r"/deps/", ~r"/node_modules/"]
},
checks: %{
enabled: [
{Credo.Check.Readability.MaxLineLength, [priority: :low, max_length: 120]},
{Credo.Check.Design.AliasUsage, [if_nested_deeper_than: 2, if_called_more_often_than: 0]},
# ... add or override checks as needed
],
disabled: [
{Credo.Check.Consistency.MultiAliasImportRequireUse, []},
{Credo.Check.Design.DuplicatedCode, []},
]
}
},
%{
name: "strict",
strict: true,
files: %{
included: ["lib/", "src/", "test/", "web/", "apps/"],
excluded: [~r"/_build/", ~r"/deps/", ~r"/node_modules/"]
},
checks: %{
enabled: [
{Credo.Check.Design.TagTODO, [priority: :high]},
{Credo.Check.Readability.Specs, []},
]
}
}
]
}# credo:disable-for-next-line
def my_function_with_long_name, do: :ok
def my_function, do: :ok # credo:disable-for-this-line# At the top of the file
# credo:disable-for-this-file Credo.Check.Readability.ModuleDoc
defmodule MyApp.LegacyModule do
# No module doc needed
end# .credo.exs
checks: %{
disabled: [
{Credo.Check.Readability.ModuleDoc, []}
]
}# .github/workflows/ci.yml
name: CI
on: [push, pull_request]
jobs:
credo:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: erlef/setup-beam@v1
with:
elixir-version: '1.15'
otp-version: '26.0'
- run: mix deps.get
- run: mix credo --strictCI must use --strict to catch all issues. Exit code 0 means clean; non-zero means issues found.
When Credo fails in CI:
mix credo# mix.exs
defp aliases do
[
"lint": ["credo --strict"],
"quality": ["format --check-formatted", "credo --strict", "sobelow --config"]
]
endCreate custom checks for project-specific patterns in three steps:
use Credo.Check in lib/credo/checks/.run/2 with Credo.Code.prewalk/2 to traverse the AST and collect issues.checks.enabled in .credo.exs.The example below detects direct Repo. calls inside LiveView modules — adapt find_issues/3 to match your own patterns:
# lib/credo/checks/no_direct_repo_in_live_view.ex
defmodule Credo.Check.NoDirectRepoInLiveView do
use Credo.Check, category: :design, base_priority: :high
@explanation """
LiveViews should not call Repo directly. Use context functions instead.
"""
def run(%Credo.SourceFile{} = source_file, params) do
issue_meta = IssueMeta.for(source_file, params)
source_file
|> Credo.Code.prewalk(&find_issues(&1, &2, issue_meta))
end
# Detect calls of the form MyApp.Repo.<any function>
defp find_issues(
{{:., _, [{:__aliases__, meta, [_, "Repo"]}, _fn]}, _, _} = ast,
issues,
issue_meta
) do
issue = format_issue(issue_meta, message: "Avoid direct Repo calls in LiveViews.", line_no: meta[:line])
{ast, [issue | issues]}
end
defp find_issues(ast, issues, _issue_meta), do: {ast, issues}
endRegister the custom check in .credo.exs:
checks: %{
enabled: [
{Credo.Check.NoDirectRepoInLiveView, []}
]
}