Skip to content
Development
Skill

/exdoc-config

Configures ExDoc for Elixir projects including mix.exs setup, extras, groups, cheatsheets, and livebooks. Use when setting up or modifying ExDoc documentation generation.

From plugin
beagle
85139 skills2 commands

Claude Code

$ npx -y skills add existential-birds/beagle --skill exdoc-config --agent claude-code

SKILL.md

exdoc-config.SKILL.md
name: exdoc-config
description: Configures ExDoc for Elixir projects including mix.exs setup, extras, groups, cheatsheets, and livebooks. Use when setting up or modifying ExDoc documentation generation.

ExDoc Configuration

Quick Reference

| Topic | Reference | |-------|-----------| | Markdown, cheatsheets (.cheatmd), livebooks (.livemd) | [references/extras-formats.md](references/extras-formats.md) | | Custom head/body tags, syntax highlighting, nesting, annotations | [references/advanced-config.md](references/advanced-config.md) |

Gates

Use this sequence before claiming ExDoc is wired correctly or that docs build:

1. **Dependencies resolved** — Run `mix deps.get` from the project root. **Pass:** exit code `0`, and `mix.exs` includes `ex_doc` as in [Dependency Setup](#dependency-setup) (or the project’s equivalent dev-only docs dep). 2. **Extra paths real** — For every path string in `extras/0` (and in `groups_for_extras/0` if used), confirm that path exists in the repo **or** you have just created that file. **Pass:** no stale or typo paths remain when you run `mix docs`. 3. **Docs build** — Run `mix docs`. **Pass:** exit code `0`, and the HTML entry exists at `<output>/index.html` (default `<project>/doc/index.html`; use `docs: [output: ...]` if you changed `output`).

For cheatsheets, livebooks, or custom head/body assets, follow the same “path exists before listing” rule; see [When to Load References](#when-to-load-references).

Dependency Setup

Add ExDoc to `mix.exs` deps:

defp deps do
  [
    {:ex_doc, "~> 0.34", only: :dev, runtime: false}
  ]
end

Project Configuration

Configure your `project/0` function in `mix.exs`:

def project do
  [
    app: :weather_station,
    version: "0.1.0",
    elixir: "~> 1.17",
    start_permanent: Mix.env() == :prod,
    deps: deps(),

    # ExDoc
    name: "WeatherStation",
    source_url: "https://github.com/acme/weather_station",
    homepage_url: "https://acme.github.io/weather_station",
    docs: docs()
  ]
end

The docs/0 Function

Define a private `docs/0` function to keep project config clean:

defp docs do
  [
    main: "readme",
    logo: "priv/static/images/logo.png",
    output: "doc",
    formatters: ["html", "epub"],
    source_ref: "v#{@version}",
    extras: extras(),
    groups_for_modules: groups_for_modules(),
    groups_for_extras: groups_for_extras()
  ]
end

Key Options

| Option | Default | Description | |--------|---------|-------------| | `main` | `"api-reference"` | Landing page module name or extra filename (without extension) | | `logo` | `nil` | Path to logo image displayed in sidebar | | `output` | `"doc"` | Output directory for generated docs | | `formatters` | `["html"]` | List of output formats (`"html"`, `"epub"`) | | `source_ref` | `"main"` | Git ref used for "View Source" links | | `assets` | `nil` | Map of source directory to target directory for static assets | | `deps` | `[]` | Links to dependency documentation |

Setting the Landing Page

The `main` option controls what users see first:

# Use the README as the landing page (most common)
docs: [main: "readme"]

# Use a specific module as the landing page
docs: [main: "WeatherStation"]

# Use a custom guide
docs: [main: "getting-started"]

The value matches the extra filename without its extension, or a module name.

Extras

Extras are additional pages beyond the API reference. Add them as a list of file paths:

defp extras do
  [
    "README.md",
    "CHANGELOG.md",
    "LICENSE.md",
    "guides/getting-started.md",
    "guides/configuration.md",
    "guides/deployment.md",
    "cheatsheets/query-syntax.cheatmd",
    "notebooks/data-pipeline.livemd"
  ]
end

Controlling Extra Titles

By default, ExDoc uses the first `h1` heading as the title. Override with a keyword tuple:

defp extras do
  [
    {"README.md", [title: "Overview"]},
    {"CHANGELOG.md", [title: "Changelog"]},
    "guides/getting-started.md"
  ]
end

Ordering

Extras appear in the sidebar in the order listed. Put the most important pages first:

defp extras do
  [
    "README.md",
    "guides/getting-started.md",
    "guides/architecture.md",
    "guides/deployment.md",
    "CHANGELOG.md"
  ]
end

Grouping

Grouping Modules

Organize modules into logical sections in the sidebar:

defp groups_for_modules do
  [
    "Sensors": [
      WeatherStation.Sensor,
      WeatherStation.Sensor.Temperature,
      WeatherStation.Sensor.Humidity,
      WeatherStation.Sensor.Pressure
    ],
    "Data Processing": [
      WeatherStation.Pipeline,
      WeatherStation.Pipeline.Transform,
      WeatherStation.Pipeline.Aggregate
    ],
    "Storage": [
      WeatherStation.Repo,
      WeatherStation.Schema.Reading,
      WeatherStation.Schema.Station
    ]
  ]
end

Use regex to group by pattern:

defp groups_for_modules do
  [
    "Sensors": [~r/Sensor/],
    "Schemas": [~r/Schema/],
    "Pipeline": [~r/Pipeline/]
  ]
end

Modules not matching any group appear under a default "Modules" heading.

Grouping Functions

Group functions within a module using `groups_for_docs`:

defp docs do
  [
    groups_for_docs: [
      "Lifecycle": &(&1[:section] == :lifecycle),
      "Queries": &(&1[:section] == :queries),
      "Mutations": &(&1[:section] == :mutations)
    ]
  ]
end

Tag functions in your module with `@doc` metadata:

@doc section: :lifecycle
def start_link(opts), do: GenServer.start_link(__MODULE__, opts)

@doc section: :queries
def get_reading(station_id), do: Repo.get(Reading, station_id)

Grouping Extras

Organize guides, cheatsheets, and notebooks in the sidebar:

defp groups_for_extras do
  [
    "Guides": [
      "guides/getting-started.md",
      "guides/configuration.md",
      "guides/deployment.md"
    ],
    "Cheatsheets": [
      "cheatsheets/query-syntax.cheatmd",
Read more
@existential-birds
Ships withbeagle

Image: NASA, Public Domain. Source Beagle is an Agent Skills marketplace: framework-aware code review, documentation, testing, architectural analysis, and git workflows for any compatible coding agent.

Stars on GitHub

Momentum

stars in total
85
Star history of existential-birds/beagle on GitHub, a chart by star-history.com

Other skills on beagle.

More skills from other plugins.

brainstorming
Auto-invoked

brainstorming

You MUST use this before any creative work - creating features, building components, adding functionality, modifying behavior, or…

@obra@obraInstall Skill
ask-matt

ask-matt

Ask which skill or flow fits your situation. A router over the skills in this repo.

skills12d309k
@mattpocock@mattpocockInstall Skill
accessibility
Auto-invoked

accessibility

Design, implement, and audit accessible UI to WCAG 2.2 Level AA across Web, iOS, and Android — semantic ARIA roles and labels,…

ecc2w293k
@affaan-m@affaan-mInstall Skill
compiler-commit

compiler-commit

Use when you want to verify compiler changes and commit with the correct convention. Runs tests, lint, and format, then commits…

react3d252k
@facebook@facebookInstall Skill

Questions about exdoc-config.

Which coding agents can use exdoc-config?
exdoc-config installs in Claude Code, Codex, Cursor, Gemini CLI, GitHub Copilot, OpenCode and Windsurf with the skills CLI, using each agent's flag shown on this page. Flowy's auto-invocation, which fires a skill when your prompt matches, runs in Claude Code only.