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.

existential-birds/beagle78 installsApache-2.0Synced Aug 26

Works with

Claude CodeCursorCodex CLIGitHub CopilotGemini CLI
---
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.
license: Apache-2.0
---

# 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:

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

## Project Configuration

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

```elixir
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:

```elixir
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:

```elixir
# 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:

```elixir
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:

```elixir
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:

```elixir
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:

```elixir
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:

```elixir
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`:

```elixir
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:

```elixir
@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:

```elixir
defp groups_for_extras do
  [
    "Guides": [
      "guides/getting-started.md",
      "guides/configuration.md",
      "guides/deployment.md"
    ],
    "Cheatsheets": [
      "cheatsheets/query-syntax.cheatmd",
      "cheatsheets/ecto-types.cheatmd"
    ],
    "Tutorials": [
      "notebooks/data-pipeline.livemd",
      "notebooks/sensor-setup.livemd"
    ]
  ]
end
```

Use glob patterns for convenience:

```elixir
defp groups_for_extras do
  [
    "Guides": ~r/guides\/.*/,
    "Cheatsheets": ~r/cheatsheets\/.*/,
    "Tutorials": ~r/notebooks\/.*/
  ]
end
```

## Dependency Doc Links

Link to documentation for your dependencies so ExDoc cross-references resolve:

```elixir
defp docs do
  [
    deps: [
      ecto: "https://hexdocs.pm/ecto",
      phoenix: "https://hexdocs.pm/phoenix",
      plug: "https://hexdocs.pm/plug"
    ]
  ]
end
```

This enables references like `t:Ecto.Schema.t/0` to link directly to the dependency docs.

## Generating Docs

```bash
# Generate HTML docs
mix docs

# Open in browser
open doc/index.html
```

## Complete mix.exs Example

```elixir
defmodule WeatherStation.MixProject do
  use Mix.Project

  @version "1.3.0"
  @source_url "https://github.com/acme/weather_station"

  def project do
    [
      app: :weather_station,
      version: @version,
      elixir: "~> 1.17",
      start_permanent: Mix.env() == :prod,
      deps: deps(),
      name: "WeatherStation",
      source_url: @source_url,
      homepage_url: "https://acme.github.io/weather_station",
      docs: docs()
    ]
  end

  defp docs do
    [
      main: "readme",
      logo: "priv/static/images/logo.png",
      source_ref: "v#{@version}",
      formatters: ["html"],
      extras: extras(),
      groups_for_modules: groups_for_modules(),
      groups_for_extras: groups_for_extras(),
      deps: [
        ecto: "https://hexdocs.pm/ecto",
        phoenix: "https://hexdocs.pm/phoenix"
      ]
    ]
  end

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

  defp groups_for_modules do
    [
      "Sensors": [~r/Sensor/],
      "Data Processing": [~r/Pipeline/],
      "Storage": [~r/Schema|Repo/]
    ]
  end

  defp groups_for_extras do
    [
      "Guides": ~r/guides\/.*/,
      "Cheatsheets": ~r/cheatsheets\/.*/,
      "Tutorials": ~r/notebooks\/.*/
    ]
  end

  defp deps do
    [
      {:phoenix, "~> 1.7"},
      {:ecto_sql, "~> 3.12"},
      {:ex_doc, "~> 0.34", only: :dev, runtime: false}
    ]
  end
end
```

## When to Load References

- Setting up cheatsheets or livebooks as extras -> extras-formats.md
- Injecting custom CSS/JS, configuring syntax highlighting, or tuning module nesting -> advanced-config.md

More Writing & Documentation skills

paper-context-resolver

lllllllama/rigorpilot-skills

Rigor Paper Context helper for README-first deep learning repo reproduction. Use only when the README and repository files leave a narrow reproduction-critical gap and the task is to resolve a specific paper detail such as dataset split, preprocessing, evaluation protocol, checkpoint mapping, or runtime assumption from primary paper sources while recording conflicts. Do not use for general paper summary, repo scanning, environment setup, command execution, title-only paper lookup, or replacing README guidance by default.

450.8k

repo-intake-and-plan

lllllllama/rigorpilot-skills

Rigor Intake helper for README-first deep learning repo reproduction. Use when the task is specifically to scan a repository, read the README and common project files, extract documented commands, classify inference, evaluation, and training candidates, and return the smallest trustworthy reproduction plan to the main orchestrator. Do not use for environment setup, asset download, command execution, final reporting, paper lookup, or end-to-end orchestration.

450.0k

minimal-run-and-audit

lllllllama/rigorpilot-skills

Rigor Run skill for README-first deep learning repo reproduction. Use when the task is specifically to capture or normalize evidence from the selected smoke test or documented inference or evaluation command and write standardized `repro_outputs/` files, including patch notes when repository files changed. Do not use for training execution, initial repo intake, generic environment setup, paper lookup, target selection, hidden scientific-meaning changes, or end-to-end orchestration by itself.

449.9k

← All Writing & Documentation skills

Check your AI visibility

One URL in, a 0–100 score and the exact fixes out.

RUN THE CHECK

Browse all the tools

15 tools across six categories
13 of them never send your data anywhere

Free · No signup · No trial clock

SEE THE DIRECTORY