Convert Figma logo to code with AI

elixir-lang logoex_doc

ExDoc produces HTML and EPUB documentation for Elixir projects

1,438
325
1,438
17

Top Related Projects

24,265

Elixir is a dynamic, functional language for building scalable and maintainable applications

21,201

Peace of mind from prototype to production

The GraphQL toolkit for Elixir

6,132

A toolkit for data mapping and language integrated query.

A curated list of amazingly awesome Elixir and Erlang libraries, resources and shiny things. Updates:

Quick Overview

ExDoc is a tool for generating documentation for Elixir projects. It produces HTML and EPUB documentation from Elixir source code, making it easy for developers to create and maintain comprehensive documentation for their libraries and applications.

Pros

  • Generates clean, well-structured HTML and EPUB documentation
  • Supports Markdown in documentation comments
  • Integrates well with the Elixir ecosystem and Mix build tool
  • Customizable themes and output options

Cons

  • Limited support for non-Elixir languages within the same project
  • May require additional setup for complex project structures
  • Learning curve for advanced customization options
  • Documentation generation can be slow for very large projects

Code Examples

  1. Basic module documentation:
defmodule MyModule do
  @moduledoc """
  This is a sample module.

  It demonstrates basic ExDoc usage.
  """

  @doc """
  Adds two numbers together.

  ## Examples

      iex> MyModule.add(2, 3)
      5

  """
  def add(a, b), do: a + b
end
  1. Generating documentation:
# In mix.exs
def project do
  [
    app: :my_app,
    version: "0.1.0",
    deps: deps(),
    docs: [
      main: "MyModule",
      extras: ["README.md"]
    ]
  ]
end

defp deps do
  [
    {:ex_doc, "~> 0.27", only: :dev, runtime: false}
  ]
end
  1. Custom grouping of modules:
# In mix.exs
def docs do
  [
    groups_for_modules: [
      "Core": [MyApp.Core.Module1, MyApp.Core.Module2],
      "Utils": [MyApp.Utils.Module1, MyApp.Utils.Module2]
    ]
  ]
end

Getting Started

  1. Add ExDoc to your project's dependencies in mix.exs:
defp deps do
  [{:ex_doc, "~> 0.27", only: :dev, runtime: false}]
end
  1. Run mix deps.get to install ExDoc.

  2. Add documentation to your modules using @moduledoc and @doc attributes.

  3. Generate documentation by running:

mix docs
  1. The generated documentation will be available in the doc/ directory.

Competitor Comparisons

24,265

Elixir is a dynamic, functional language for building scalable and maintainable applications

Pros of Elixir

  • Core language implementation with a broader scope and functionality
  • Provides the foundation for the entire Elixir ecosystem
  • Includes the Erlang/OTP integration, enabling robust concurrent and distributed systems

Cons of Elixir

  • Larger codebase, potentially more complex to contribute to or understand fully
  • Slower release cycle due to its core nature and need for extensive testing
  • Requires more system resources to build and run

Code Comparison

Elixir (core language feature):

defmodule Example do
  def greet(name) do
    IO.puts("Hello, #{name}!")
  end
end

ExDoc (documentation generation):

defmodule MyApp do
  @moduledoc """
  Documentation for MyApp.
  """

  @doc "Prints hello"
  def hello, do: :world
end

Summary

Elixir is the core language implementation, providing the foundation for the entire Elixir ecosystem, including features like concurrency and OTP integration. It has a broader scope but is more complex and resource-intensive. ExDoc, on the other hand, is a specialized tool for generating documentation from Elixir code. It's more focused in purpose, easier to contribute to, and has a faster release cycle. While Elixir defines the language itself, ExDoc enhances the development experience by improving code documentation.

21,201

Peace of mind from prototype to production

Pros of Phoenix

  • Full-featured web framework with built-in routing, controllers, and views
  • Real-time capabilities with channels for WebSocket communication
  • Scalable architecture designed for high-performance applications

Cons of Phoenix

  • Steeper learning curve due to its comprehensive feature set
  • Potentially overkill for simple documentation projects
  • Requires more setup and configuration compared to ExDoc

Code Comparison

ExDoc (generating documentation):

defmodule MyApp do
  @moduledoc """
  Documentation for MyApp
  """
  def hello do
    "Hello, World!"
  end
end

Phoenix (defining a route and controller):

defmodule MyAppWeb.Router do
  use MyAppWeb, :router
  get "/", PageController, :index
end

defmodule MyAppWeb.PageController do
  use MyAppWeb, :controller
  def index(conn, _params) do
    render(conn, "index.html")
  end
end

Summary

ExDoc is a specialized tool for generating documentation from Elixir code, while Phoenix is a comprehensive web framework. ExDoc is simpler to use for documentation purposes, but Phoenix offers a full suite of features for building web applications. The choice between them depends on the project's requirements: use ExDoc for straightforward documentation needs, and Phoenix for building robust web applications with advanced features like real-time communication.

The GraphQL toolkit for Elixir

Pros of Absinthe

  • Specialized for GraphQL API development in Elixir
  • Provides a robust schema definition DSL
  • Offers built-in support for real-time subscriptions

Cons of Absinthe

  • Steeper learning curve for developers new to GraphQL
  • More complex setup compared to ExDoc's straightforward documentation generation
  • Limited to GraphQL-specific use cases

Code Comparison

ExDoc (documentation generation):

defmodule MyModule do
  @moduledoc """
  This module does something awesome.
  """
  def my_function(arg) do
    # Function implementation
  end
end

Absinthe (GraphQL schema definition):

defmodule MySchema do
  use Absinthe.Schema

  query do
    field :my_query, :string do
      resolve fn _, _, _ ->
        {:ok, "Query result"}
      end
    end
  end
end

While ExDoc focuses on generating documentation from code comments, Absinthe provides a DSL for defining GraphQL schemas and resolvers. ExDoc is essential for creating project documentation, whereas Absinthe is specifically designed for building GraphQL APIs in Elixir applications. ExDoc is more universally applicable across Elixir projects, while Absinthe caters to a specific architectural pattern. Both tools serve different purposes within the Elixir ecosystem, with ExDoc enhancing code readability and Absinthe facilitating API development.

6,132

A toolkit for data mapping and language integrated query.

Pros of Ecto

  • More comprehensive database toolkit with query building, migrations, and schemas
  • Supports multiple databases (PostgreSQL, MySQL, SQLite)
  • Active development with frequent updates and improvements

Cons of Ecto

  • Steeper learning curve due to its broader scope and functionality
  • Requires more setup and configuration for basic usage
  • Larger codebase and dependencies

Code Comparison

Ecto query example:

query =
  from u in User,
    where: u.age > 18,
    select: u.name

Repo.all(query)

ExDoc documentation example:

defmodule MyModule do
  @moduledoc """
  This module does something awesome.
  """

  @doc """
  Performs an amazing operation.
  """
  def amazing_function(arg) do
    # Function implementation
  end
end

Summary

Ecto is a powerful database toolkit for Elixir, offering a wide range of features for database interactions. ExDoc, on the other hand, is focused on generating documentation for Elixir projects. While Ecto provides more functionality for database operations, it comes with increased complexity. ExDoc offers a simpler, more focused tool for improving code documentation. The choice between the two depends on the specific needs of your project: database management or documentation generation.

A curated list of amazingly awesome Elixir and Erlang libraries, resources and shiny things. Updates:

Pros of awesome-elixir

  • Comprehensive list of Elixir resources, libraries, and tools
  • Community-driven with frequent updates and contributions
  • Serves as a valuable reference for Elixir developers of all levels

Cons of awesome-elixir

  • Not focused on generating documentation for Elixir projects
  • Lacks built-in functionality for code analysis or documentation generation
  • Requires manual curation and maintenance

Code comparison

While a direct code comparison isn't relevant due to the different nature of these projects, here's a brief example of how they might be used:

awesome-elixir (README.md):

## Testing
* [ExUnit](https://hexdocs.pm/ex_unit/ExUnit.html) - Built-in test framework for Elixir.
* [Mox](https://github.com/plataformatec/mox) - Mocks and explicit contracts for Elixir.

ex_doc (usage in mix.exs):

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

Summary

awesome-elixir is a curated list of Elixir resources, while ex_doc is a tool for generating documentation for Elixir projects. awesome-elixir provides a comprehensive overview of the Elixir ecosystem, making it easier for developers to discover useful libraries and tools. However, it doesn't offer the specific functionality of ex_doc, which focuses on creating high-quality documentation for individual Elixir projects.

Convert Figma logo designs to code with AI

Visual Copilot

Introducing Visual Copilot: A new AI model to turn Figma designs to high quality code using your components.

Try Visual Copilot

README

ExDoc

Build Status

ExDoc is a tool to generate documentation for Erlang and Elixir projects. To see an example, you can access Elixir's official docs.

Features

ExDoc ships with many features:

  • Automatically generates online- and offline-accessible HTML and EPUB documents from your API documentation.
  • Responsive design, covering phones and tablets.
  • Support for custom pages, guides, livebooks and cheatsheets.
  • Support for custom grouping of modules, functions, and pages in the sidebar.
  • Customizable logo.
  • A direct link back to the source code for every documented entity.
  • Full-text search.
  • Keyboard shortcuts. (Press ? to show help.)
  • Quick-search with autocompletion support. (s keyboard shortcut.)
  • Go-to shortcut with auto-complete to take the reader to any HexDocs package documentation. (g keyboard shortcut.)
  • Support for night mode, activated according to the browser preference.
  • Tooltips for links to modules and functions, both for the current project and other projects.
  • Version dropdown, automatically configured when hosted on HexDocs.

Usage

You can use ExDoc with Mix (recommended for Elixir projects), with Rebar (recommended for Erlang projects), or via the command line.

Mix

ExDoc requires Elixir v1.12 or later. Then add ExDoc as a dependency:

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

Then run mix deps.get.

Erlang development environment {: .warning}

Some Operating System distributions split Erlang into multiple packages, and at least one ExDoc dependency (earmark_parser) requires the Erlang development environment. If you see a message like "/usr/lib/erlang/lib/parsetools-2.3.1/include/yeccpre.hrl: no such file or directory", it means you lack this environment. For instance, on the Debian operating system and its derivatives, you need to apt install erlang-dev.

ExDoc will automatically pull in information from your projects, such as the application and version. However, you may want to set :name, :source_url and :homepage_url in order to have nicer output from ExDoc:

def project do
  [
    app: :my_app,
    version: "0.1.0-dev",
    deps: deps(),

    # Docs
    name: "MyApp",
    source_url: "https://github.com/USER/PROJECT",
    homepage_url: "http://YOUR_PROJECT_HOMEPAGE",
    docs: [
      main: "MyApp", # The main page in the docs
      logo: "path/to/logo.png",
      extras: ["README.md"]
    ]
  ]
end

Now you are ready to generate your project documentation with mix docs. To see all options available, run mix help docs.

To learn about how to document your projects, see Elixir's writing documentation page.

Rebar3

From Erlang/OTP 24+, you can use ExDoc to render your Erlang documentation written with EDoc. See rebar3_ex_doc for more information.

CLI

You can use ExDoc via the command line.

  1. Install ExDoc as an escript:

    $ mix escript.install hex ex_doc
    
  2. Now you are ready to use it in your projects. Move into your project directory and make sure it's compiled:

    $ cd PATH_TO_YOUR_PROJECT
    $ mix compile
    
  3. Invoke the ex_doc executable from your project:

    $ ex_doc "PROJECT_NAME" "PROJECT_VERSION" _build/dev/lib/project/ebin -m "PROJECT_MODULE" -u "https://github.com/GITHUB_USER/GITHUB_REPO" -l path/to/logo.png
    

    Examples of appropriate values:

    PROJECT_NAME    => Ecto
    PROJECT_VERSION => 0.1.0
    PROJECT_MODULE  => Ecto (the main module provided by the library)
    GITHUB_USER     => elixir-lang
    GITHUB_REPO     => ecto
    

You can specify a config file via the --config option, both Elixir and Erlang formats are supported. Invoke ex_doc without arguments to learn more.

Syntax highlighting

ExDoc uses the makeup project for syntax highlighting. By default, highlighters for Erlang and Elixir are included. To syntax-highlight other languages, simply add the equivalent makeup_LANGUAGE package to your mix.exs/rebar.config file. For example, for HTML support you would add:

Elixir (Mix)

{:makeup_html, ">= 0.0.0", only: :dev, runtime: false}

Erlang (Rebar3)

{makeup_html, "0.1.1"}

You can find all supported languages under the Makeup organization on GitHub and view them at Makeup's website.

Additional pages

You can publish additional pages in your project documentation by configuring them as :extras. The following formats and extensions are supported:

  • Markdown (.md extension) - useful for general long-term text. Learn more.

  • Cheatsheets (.cheatmd extension) - useful for discovery and quick reference. Learn more.

  • Livebooks (.livemd extension) - useful for tutorials, interactive examples, and deep dives. Learn more.

For example, you can set your :extras to:

Elixir

extras: ["README.md", "LICENSE", "tutorial.livemd", "cheatsheet.cheatmd"]

Run mix help docs for more information on configuration.

Erlang

{extras, [<<"README.md">>, <<"cheatsheet.cheatmd">>]}.

Metadata

ExDoc supports metadata keys in your documentation.

Elixir

In Elixir, you can add metadata to modules and functions.

For a module, use @moduledoc, which is equivalent to adding the annotation to everything inside the module (functions, macros, callbacks, types):

@moduledoc since: "1.10.0"

For a function, use @doc:

@doc since: "1.13.1"

Erlang

In Erlang's EDoc:

%% @since 0.1.0

The following metadata is available for both modules and functions:

  • deprecated (binary) - marks a module/function as deprecated, with the given string as the reason.
  • since (binary) - declares a module/function available from a particular version.

The following metadata is available for modules:

  • tags (list of atoms) - a list of strings to be added as tags to the module. (Not supported by EDoc.)

Auto-linking

ExDoc for Elixir and Erlang will automatically generate links across modules and functions if you enclose them in backticks.

Elixir

ExDoc will automatically link modules, functions, types or callbacks defined in your project and its dependencies (including Erlang and Elixir). ExDoc will automatically link to it at the dependency's documentation at hexdocs.pm. The link can be configured by setting docs: [deps: [my_dep: "https://path/to/docs/"]] in your mix.exs.

ExDoc supports linking to modules (`MyModule` and `m:MyModule`), functions (`MyModule.function/1`), types (`t:MyModule.type/2`) and callbacks (`c:MyModule.callback/3`). If you want to link a function, type or callback in the current module, you may skip the module name, for example: `function/1`.

You can also use custom text, such as [custom text](`MyModule.function/1`). Link to extra pages using the syntax [Up and running](Up and running.md). The final link will be automatically converted to up-and-running.html.

Link to extra pages in another application using the syntax [Writing Documentation](`e:elixir:writing-documentation.html`), skipping the directory in which the page is. The final link will be automatically converted to https://hexdocs.pm/elixir/writing-documentation.html.

It is also possible to place anchors after the module name and extra pages. For example:

  • `m:Keyword#module-duplicate-keys-and-ordering` will create a link to https://hexdocs.pm/elixir/Keyword.html#module-duplicate-keys-and-ordering

  • `e:elixir:syntax-reference.md#expressions` will create a link to https://hexdocs.pm/elixir/syntax-reference.html#expressions

Erlang

ExDoc will automatically link modules, functions, types or callbacks defined in your project and its dependencies (including Erlang and Elixir). ExDoc will automatically link to it at the dependency's documentation at hexdocs.pm. The link can be configured by setting docs: [deps: [my_dep: "https://path/to/docs/"]] in your mix.exs. The link can be configured by setting {docs, [{deps, [{my_dep, "https://path/to/docs/"}]}]} in your rebar3.config.

ExDoc supports linking to modules (`m:my_module`), functions (`my_module:function/1`), types (`t:my_module:type/2`) and callbacks (`c:my_module:callback/3`). If you want to link a function, type or callback in the current module, you may skip the module name; e.g.: `function/1`.

You can also use custom text, such as [custom text](`my_module:function/1`). This also allows you to refer to Erlang/OTP modules: [The array module](`array`) (note that when a module is given as the link target, it is not necessary nor possible to use the m: prefix).

Link to extra pages using the syntax [Up and running](Up and running.md). The final link will be automatically converted to up-and-running.html.

Link to extra pages in another application using the syntax [Using unicode](`e:stdlib:unicode_usage.html`), skipping the directory in which the page is. The final link will be automatically converted to https://hexdocs.pm/elixir/writing-documentation.html.

It is also possible to place anchors after the module name and extra pages. For example:

  • `m:argparse#quick-start` will create a link to https://erlang.org/doc/man/argparse#quick-start

  • `e:stdlib:unicode-usage.md#what-unicode-is` will create a link to https://erlang.org/doc/apps/stdlib/unicode-usage.html#what-unicode-is

Admonition blocks

You may want to draw attention to certain statements by taking them out of the content's flow and labeling them with a priority. Such statements are called admonitions. (They are also known as asides or callouts.) An admonition block is rendered based on the assigned label or class. ExDoc supports warning, error, info, tip and neutral tags, on header levels h3 and h4.

The syntax is as follows:

> #### Error {: .error}
>
> This syntax will render an error block

The result for the previous syntax is:

Error {: .error}

This syntax will render an error block

For example, if you change the class name to neutral, you get the same admonition block in neutral style:

Neutral {: .neutral}

This syntax will render a neutral block

Tabsets

Where only one section of content of a series is likely to apply to the reader, you may wish to define a set of tabs.

This example contains code blocks, separating them into tabs based on language:

Elixir

IO.puts "Hello, world!"

Erlang

io:fwrite("Hello, world!\n").

Tabbed content must be defined between <!-- tabs-open --> and <!-- tabs-close --> HTML comments. Each h3 heading results in a new tab panel, with its text setting the tab button label.

Here is the above example's source:

<!-- tabs-open -->

### Elixir

```elixir
IO.puts "Hello, world!"
```

### Erlang

```erlang
io:fwrite("Hello, world!\n").
```

<!-- tabs-close -->

Extensions

ExDoc renders Markdown content for you, but you can extend it to render complex objects on the page using JavaScript. To inject custom JavaScript into every page, add this to your configuration:

docs: [
  # ...
  before_closing_head_tag: &before_closing_head_tag/1,
  before_closing_body_tag: &before_closing_body_tag/1
]

# ...

defp before_closing_head_tag(:html) do
  """
  <!-- HTML injected at the end of the <head> element -->
  """
end

defp before_closing_head_tag(:epub), do: ""

defp before_closing_body_tag(:html) do
  """
  <!-- HTML injected at the end of the <body> element -->
  """
end

defp before_closing_body_tag(:epub), do: ""

Besides an anonymous function, you can also pass a module-function-args tuple. It will call the given module and function, with the format prefixed to the arguments:

docs: [
  # ...
  before_closing_head_tag: {MyModule, :before_closing_head_tag, []},
  before_closing_body_tag: {MyModule, :before_closing_body_tag, []}
]

Or you can pass a map where the key is the format:

docs: [
  # ...
  before_closing_head_tag: %{html: "...", epub: "..."},
  before_closing_body_tag: %{html: "...", epub: "..."}
]

Rendering Math

If you write TeX-style math in your Markdown, such as $\sum_{i}^{N} x_i$, it ends up as raw text on the generated pages. To render expressions, we recommend using KaTeX, a JavaScript library that turns expressions into graphics. To load and trigger KaTeX on every documentation page, we can insert the following HTML:

<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/katex@0.16.4/dist/katex.min.css" integrity="sha384-vKruj+a13U8yHIkAyGgK1J3ArTLzrFGBbBc0tDp4ad/EyewESeXE/Iv67Aj8gKZ0" crossorigin="anonymous">
<script defer src="https://cdn.jsdelivr.net/npm/katex@0.16.4/dist/katex.min.js" integrity="sha384-PwRUT/YqbnEjkZO0zZxNqcxACrXe+j766U2amXcgMg5457rve2Y7I6ZJSm2A0mS4" crossorigin="anonymous"></script>

<link href="https://cdn.jsdelivr.net/npm/katex-copytex@1.0.2/dist/katex-copytex.min.css" rel="stylesheet" type="text/css">
<script defer src="https://cdn.jsdelivr.net/npm/katex-copytex@1.0.2/dist/katex-copytex.min.js" crossorigin="anonymous"></script>

<script defer src="https://cdn.jsdelivr.net/npm/katex@0.16.4/dist/contrib/auto-render.min.js" integrity="sha384-+VBxd3r6XgURycqtZ117nYw44OOcIax56Z4dCRWbxyPt0Koah1uHoK0o4+/RRE05" crossorigin="anonymous"
  onload="renderMathInElement(document.body, {
    delimiters: [
      {left: '$$', right: '$$', display: true},
      {left: '$', right: '$', display: false},
    ]
  });"></script>
</script>

For more details and configuration options, see the KaTeX Auto-render Extension.

Rendering Vega-Lite plots

Snippets are also objects you may want to render in a special manner. For example, assuming your Markdown includes Vega-Lite specification in vega-lite code snippets:

<script defer src="https://cdn.jsdelivr.net/npm/vega@5.20.2"></script>
<script defer src="https://cdn.jsdelivr.net/npm/vega-lite@5.1.1"></script>
<script defer src="https://cdn.jsdelivr.net/npm/vega-embed@6.18.2"></script>
<script>
  document.addEventListener("DOMContentLoaded", function () {
    for (const codeEl of document.querySelectorAll("pre code.vega-lite")) {
      try {
        const preEl = codeEl.parentElement;
        const spec = JSON.parse(codeEl.textContent);
        const plotEl = document.createElement("div");
        preEl.insertAdjacentElement("afterend", plotEl);
        vegaEmbed(plotEl, spec);
        preEl.remove();
      } catch (error) {
        console.log("Failed to render Vega-Lite plot: " + error)
      }
    }
  });
</script>

For more details and configuration options, see vega/vega-embed.

Rendering Mermaid graphs

Similarly to the example above, if your Markdown includes Mermaid graph specification in mermaid code snippets:

<script>
  function mermaidLoaded() {
    mermaid.initialize({
      startOnLoad: false,
      theme: document.body.className.includes("dark") ? "dark" : "default"
    });
    let id = 0;
    for (const codeEl of document.querySelectorAll("pre code.mermaid")) {
      const preEl = codeEl.parentElement;
      const graphDefinition = codeEl.textContent;
      const graphEl = document.createElement("div");
      const graphId = "mermaid-graph-" + id++;
      mermaid.render(graphId, graphDefinition).then(({svg, bindFunctions}) => {
        graphEl.innerHTML = svg;
        bindFunctions?.(graphEl);
        preEl.insertAdjacentElement("afterend", graphEl);
        preEl.remove();
      });
    }
  }
</script>
<script async src="https://cdn.jsdelivr.net/npm/mermaid@10.2.3/dist/mermaid.min.js" onload="mermaidLoaded();"></script>

For more details and configuration options, see the Mermaid usage docs.

Contributing

The easiest way to test changes to ExDoc is to locally rebuild the app and its own documentation:

  1. Run mix setup to install all dependencies
  2. Run mix build to generate the docs and open up the generated doc/index.html
  3. (optional) Run npm run --prefix assets build:watch if working on assets for automatic recompilation
  4. Run mix lint to check linting and formatting (and mix fix to automatically fix it)
  5. (important) Do not add the files in the formatters/ directory to your commits, those will be handled by the maintainers

See the README in the assets/ directory for more information on working on the assets.

License

ExDoc source code is released under the Apache 2 License. The generated contents, however, are under different licenses based on projects used to help render HTML, including CSS, JS, and other assets.

Any documentation generated by ExDoc, or any documentation generated by any "Derivative Works" (as specified in the Apache 2 License), must include a direct, readable, and visible link to the ExDoc repository on each rendered material. For HTML pages, every single page is a rendered material. For PDF, EPUB and other ebook formats, the whole body of documentation is a rendered material.