Exdoc Config
/install exdoc-config
ExDoc Configuration
Quick Reference
| Topic | Reference |
|---|---|
| Markdown, cheatsheets (.cheatmd), livebooks (.livemd) | references/extras-formats.md |
| Custom head/body tags, syntax highlighting, nesting, annotations | references/advanced-config.md |
Gates
Use this sequence before claiming ExDoc is wired correctly or that docs build:
- Dependencies resolved — Run
mix deps.getfrom the project root. Pass: exit code0, andmix.exsincludesex_docas in Dependency Setup (or the project’s equivalent dev-only docs dep). - Extra paths real — For every path string in
extras/0(and ingroups_for_extras/0if used), confirm that path exists in the repo or you have just created that file. Pass: no stale or typo paths remain when you runmix docs. - Docs build — Run
mix docs. Pass: exit code0, and the HTML entry exists at\x3Coutput>/index.html(default\x3Cproject>/doc/index.html; usedocs: [output: ...]if you changedoutput).
For cheatsheets, livebooks, or custom head/body assets, follow the same “path exists before listing” rule; see 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",
"cheatsheets/ecto-types.cheatmd"
],
"Tutorials": [
"notebooks/data-pipeline.livemd",
"notebooks/sensor-setup.livemd"
]
]
end
Use glob patterns for convenience:
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:
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
# Generate HTML docs
mix docs
# Open in browser
open doc/index.html
Complete mix.exs Example
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
- Make sure OpenClaw is installed (local or Docker)
- Run the install command in chat:
/install exdoc-config - After installation, invoke the skill by name or use
/exdoc-config - Provide required inputs per the skill's parameter spec and get structured output
What is Exdoc Config?
Configures ExDoc for Elixir projects including mix.exs setup, extras, groups, cheatsheets, and livebooks. Use when setting up or modifying ExDoc documentatio... It is an AI Agent Skill for Claude Code / OpenClaw, with 172 downloads so far.
How do I install Exdoc Config?
Run "/install exdoc-config" in the OpenClaw or Claude Code chat to install it in one step — no extra setup required.
Is Exdoc Config free?
Yes, Exdoc Config is completely free, licensed under MIT-0. You can download, install and use it at no cost.
Which platforms does Exdoc Config support?
Exdoc Config is cross-platform and runs anywhere OpenClaw / Claude Code is available (cross-platform).
Who created Exdoc Config?
It is built and maintained by Kevin Anderson (@anderskev); the current version is v1.2.1.