How to get pleasant documentation for a library using Dune?

I’m working to publish a small library using Dune. The documentation automatically generated by dune build @doc looks fairly unpleasant to me, as I don’t see an easy way to explain what the library is about. I’m creating this topic in case I am missing something simple, and to get other people to share their library-documentation practices or examples.

Problem description

For the sake of the example let’s imagine that the library is called Foo and contains three modules A, B and C. I’m using the standard dune approach of wrapped modules, so I get three compilation units Foo.A, Foo.B, Foo.C. Each module has a .mli file with documentation comments.

When I run dune build @doc, dune generates an index.html file with basically no content, pointing to a foo/index.html file with basically no content, pointing to a foo/Foo/index.html looking like this:

Up – foo » Foo

Module Foo

module A : sig ... end

module B : sig ... end

module C : sig ... end

It’s easy to skip the first two pages, and use the third page as a landing page for the documentation of my library. However, this landing page is not very pleasant:

  1. It should explain what the library is about.
  2. It should briefly describe what each module does, so that users know which module they want to look at first. (Note: this one is in fact solved, see below.)

My problem is: what should I change in my Dune setup to be able to do this?

I have read the dune documentation on documentation, but I could not find an answer to this question.

Rough ideas

Roughly I see two ways to get what I want, that I have not tried yet:

  1. I could write my own landing page for the library as a separate doc.mld file, use the (documentation) stanza to get it included in the built documentation, and use this as the entry point into my library.
  2. In could write my own module instead of using Dune’s default wrapped-module scaffolding, inserting my own module A = Foo__A aliases, with documentation comments in the standard style. Then I suppose that foo/Foo/index.html would get this content in the way I expect.

They feel a bit complex to me, and (2) involves the tedious work of redoing the wrapping logic myself. I guess that (1) is not so bad, and I would be inclined to do this if it was documented somewhere as the recommended approach.

(Maybe there is some odoc option that would help solve this problem?)

Examples from other people?

Do you have a library built using dune with nice documentation? If so, can you show the documentation and the corresponding sources (in particular dune setup)?


I think the documentation of Streaming is a great example of the option 1 you describe.

The corresponding Dune setup can be found here

That’s also the approach we took for Opium’s documentation, although the index page is certainly not as impressive as Streaming’s.


Thanks! It looks like these systems rely on an undocumented feature of the (documentation) stanza (or odoc), which is that a user-provided index.mld file will implicitly replace the automatically-generated index.mld file, giving a reasonably natural result.

The opium documentation also uses the {!modules: modulename ...} markup directive, which is a way to include the module index within this manually-written landing page without having to duplicate the markup. Streaming¹ uses inline html instead to get a nicer-looking result, but it is too much effort. Maybe there is a better way, or the tools could be improved to make this easier.

¹: I’m ashamed to admit that I wasn’t aware of this very nice library Streaming, am I consuming the wrong sources of information on the OCaml ecosystem?

Finally, the Opium documentation manifestly has a short synopsis for each module in its listing, which corresponds to my “It should briefly describe what each module does” requirement. I believe that this comes from the first line of the first documentation comment of the module. There are module-global documentation comments in the library I’m working on, but they do not include such first-line headers.

Once I have the impression of understanding what is a good way to do this, I may try to contribute better documentation in dune.


I confirm this feature is here to stay, is the right one to customize your index page, and in the future will benefit from good support from odoc directly.

I would strongly advise to use the modules markup directive, and to suggests output improvements on odoc’s bug instead of hacking HTML together. We could absolutely add the synopsis of the module here, for instance.


This is also the correct way to customize the landing page of your package for odig generated doc sets, see here for more information.

There’s an open issue about that here.


You are in the right place, Streaming was announced[1] here :slight_smile:

[1] [ANN] First release of streaming

1 Like

I sent a PR to better document the use of index.mld in the Dune documentation: dune#4146.