# \[ANN\] Release of odoc 2.0.0

**URL:** https://discuss.ocaml.org/t/ann-release-of-odoc-2-0-0/8582
**Category:** Ecosystem
**Tags:** odoc
**Created:** [October 6, 2021, 5:23pm UTC](https://discuss.ocaml.org/t/ann-release-of-odoc-2-0-0/8582 "2021-10-06T17:23:40Z")
**Posts on this page:** 18
**Page:** 1

<div class="post-metadata">

### Author: ![jonludlam](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/jonludlam/32/101_2.png) [@jonludlam](https://discuss.ocaml.org/u/jonludlam)
#### Post date: [October 6, 2021, 5:23pm UTC](https://discuss.ocaml.org/t/ann-release-of-odoc-2-0-0/8582/1 "2021-10-06T17:23:40Z")

</div>

Hot on the heels of the OCaml 4.13 announcement(s!), the `odoc` team is pleased to announce the release of `odoc 2.0.0`!

_tl;dr:_  
The new version produces [much better output](https://ocaml-doc.github.io/odoc-examples/core_kernel/Core_kernel/Bigbuffer/index.html) than [the old version](https://ocaml.janestreet.com/ocaml-core/latest/doc/core_kernel/Core_kernel/Bigbuffer/index.html), it’s the engine at the core of the package docs in [v3.ocaml.org](https://v3.ocaml.org/packages), and it also has a [new website](https://ocaml.github.io/odoc).

This release has been a long time coming – years! – and contains several notable improvements over the `odoc 1.5` series: a new language model, a new rendering layer allowing output in several formats, and improved control over the output structure.

## New Features

### New Language Model

The internal library used by `odoc` that models the OCaml module system has been completely rewritten over a multi-year effort by @jonludlam and @Julow, according to a design by @lpw25. The rewrite gives `odoc` a much better understanding of the module system compared to the original implementation. This library is used for two main processes:

1. To perform _expansions_, which is the process where `odoc` takes complex module type expressions like [this one from tyxml](https://ocaml.github.io/odoc/deps/tyxml/Html_f/index.html#module-Make):

```auto
module Make
    (Xml : Xml_sigs.T with type ('a, 'b) W.ft = 'a -> 'b)
    (Svg : Svg_sigs.T with module Xml := Xml)
  : Html_sigs.Make(Xml)(Svg).T
    with type +'a elt = Xml.elt
     and type +'a attrib = Xml.attrib

```

Then turns it into an [output page](https://ocaml.github.io/odoc/deps/tyxml/Html_f/Make/index.html) containing the correct types, values, modules, includes, and documentation.

1. To perform _resolutions_, which is where `odoc` handles complex paths found in OCaml source in order to calculate the correct definition link. For example, in the following snippet:

```auto
module type A = sig
  module M : sig module type S end
  module N : M.S
end

module B : sig module type S = sig type t end end

module C : A with module M = B with type N.t = int

type t = C.N.t

```

resolution is the process by which `odoc` determines which documentation page to take you when you click on `C.N.t`.

The new model has logic to handle many features of the OCaml language, as can be explored [here](http://ocaml.github.io/odoc/features.html).

A particularly important improvement is in handling canonical modules (explained in the link above). The upshot of this is that there should never be any more odd double underscores leaking into your docs!

For some more info on this, as well as the new output renderers, see [our talk at the OCaml workshop last year](https://watch.ocaml.org/videos/watch/2acebff9-25fa-4733-83cc-620a65b12251)

### New Output Renderers

@Drup put a considerable amount of work into replacing the `odoc 1.5` custom HTML generator with a new rendering layer. This features a new intermediate format allowing new output formats to be added far more easily than before.

Included in `odoc 2.0` are renderers for HTML and man pages (both contributed by @Drup) and LaTeX (contributed by @Octachron). The LaTeX renderer has already been integrated into the OCaml build process to generate docs (see [https://github.com/ocaml/ocaml/pull/9997](https://github.com/ocaml/ocaml/pull/9997) and related PRs). @jonludlam also made an alternative HTML renderer designed specifically for [v3.ocaml.org](https://v3.ocaml.org/packages). Finally, a new markdown renderer is being prepared by @lubegasimon and should land in the next release.

We look forward to many new renderers being created for the varied use cases present in the community!

### Output Structure

`odoc 2.0` introduces a new mechanism to specify the structure of the files produced. Although it’s a relatively simple new feature, it nevertheless has enabled `odoc` to be used in new ways. In particular, it has allowed `odoc` to construct the  
package documentation for the new OCaml website, [v3.ocaml.org](https://v3.ocaml.org/packages). There is also an [example driver](https://ocaml.github.io/odoc/driver.html), showing how `odoc` can be used to construct a stand-alone website for an OCaml package that contains fully-linked documentation for a package and all of its dependencies. This has been used to create `odoc`’s [new website](https://ocaml.github.io/odoc).

### New Drivers

Like the OCaml compiler itself, running `odoc` on your code requires careful sequencing of the invocations to produce the correct result. Fortunately both `dune` and `odig` understand how to do this, so most users don’t need to know the details. If you want more than these tools provide though, we’ve written a simple [reference driver](https://ocaml.github.io/odoc/driver.html), documenting exactly what’s necessary to use `odoc` to produce rich documentation. A more complete (and more complex) example is the tool [voodoo](https://github.com/ocaml-doc/voodoo), which is being used to create the docs for [v3.ocaml.org](https://v3.ocaml.org/packages).

## [v3.ocaml.org](https://v3.ocaml.org)

As previously posted, the new version of the OCaml website has been under development for some time now, and an important new feature is the integration of package listings, including documentation for every version of every package. More has been written about this elsewhere, but it’s important to note that the new [OCaml.org](http://OCaml.org) website required a preview version of `odoc 2.0` to work. We’ve made a few bug fixes since then, so we will update the pipeline to use the released version very soon. For more info on the pipeline to build the docs, see [our recent talk](https://watch.ocaml.org/videos/watch/9bb452d6-1829-4dac-a6a2-46b31050c931) at this year’s OCaml Workshop.

## New Website

The website for `odoc` has been improved with guides for [documentation authors](https://ocaml.github.io/odoc/odoc_for_authors.html), [integrators](https://ocaml.github.io/odoc/driver.html), and [contributors](https://ocaml.github.io/odoc/contributors.html). This site is intended to grow over time with more content to help people write docs for their packages.

## OCamldoc?

This release, particularly because of the new output renderers, puts `odoc` in a place where it supercedes OCamldoc in most respects. There are a few features we’re missing (see [the comparison](https://ocaml.github.io/odoc/ocamldoc_differences.html) in the docs), including  
most notably that we don’t render the source (OCamldoc’s `--keep-code` argument), and that there is no support for custom tags. If `odoc` is lacking features that you’re currently relying on in OCamldoc, we’d love to hear from you!

## More Docs!

Finally, I’d like to use this opportunity to launch an invitation. With [v3.ocaml.org](https://v3.ocaml.org/packages) now showing all the package docs in their current state, I’d like to invite all our package authors, maintainers, contributors, and users to take a look over their favourite packages and see what the documentation looks like. Good documentation is one of the [most important requests](https://discuss.ocaml.org/t/suggestions-from-the-ocaml-survey-result/6791) from the previous OCaml developer surveys, and with [v3.ocaml.org](https://v3.ocaml.org/) as a new documentation hub, now is a great time to be making improvements where they’re required. With this new release of `odoc`, previewing your docs should be as simple as `dune build @doc`.

Some packages already have great docs - a few examples are:

- [brr](https://v3.ocaml.org/p/brr/0.0.1/doc/ffi_manual.html)
- [lwt](https://v3.ocaml.org/p/lwt/5.4.2/doc/index.html)
- [mimic](https://v3.ocaml.org/p/mimic/0.0.3/doc/index.html)
- [streaming](https://v3.ocaml.org/p/streaming/0.8.0/doc/index.html)
- [uucp](https://v3.ocaml.org/p/uucp/13.0.0/doc/index.html)

many others have more patchy docs. Let’s fix that!

We’re also looking for more contributors to `odoc`. It’s much improved now, but there’s still [plenty more to do](https://github.org/ocaml/odoc/issues). Come and join the fun!

---

<div class="post-metadata">

### Author: ![davesnx](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/davesnx/32/2949_2.png) [@davesnx](https://discuss.ocaml.org/u/davesnx)
#### Post date: [October 6, 2021, 5:40pm UTC](https://discuss.ocaml.org/t/ann-release-of-odoc-2-0-0/8582/2 "2021-10-06T17:40:42Z")

</div>

Congrats on the release, looks like a great improvement! Some of the excuses to write documentation has been the tooling, it might not be the case anymore 😃

btw, all the `v3.ocaml.org/p/*` links are broken:

- [brr](https://v3.ocaml.org/p/brr/0.0.1/doc/ffi_manual.html)
- [lwt](https://v3.ocaml.org/p/lwt/5.4.2/doc/index.html)
- [mimic](https://v3.ocaml.org/p/mimic/0.0.3/doc/index.html)
- [streaming](https://v3.ocaml.org/p/streaming/0.8.0/doc/index.html)
- [uucp](https://v3.ocaml.org/p/uucp/13.0.0/doc/index.html)

---

<div class="post-metadata">

### Author: ![lubegasimon](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/lubegasimon/32/2185_2.png) [@lubegasimon](https://discuss.ocaml.org/u/lubegasimon)
#### Post date: [October 6, 2021, 6:08pm UTC](https://discuss.ocaml.org/t/ann-release-of-odoc-2-0-0/8582/3 "2021-10-06T18:08:28Z")

</div>

Not only that, but also contributing to `odoc` and how to write good documentation 😄 — [odoc (odoc)](https://ocaml.github.io/odoc/)

---

<div class="post-metadata">

### Author: ![jonludlam](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/jonludlam/32/101_2.png) [@jonludlam](https://discuss.ocaml.org/u/jonludlam)
#### Post date: [October 6, 2021, 6:20pm UTC](https://discuss.ocaml.org/t/ann-release-of-odoc-2-0-0/8582/4 "2021-10-06T18:20:56Z")

</div>

That’s odd! All the links seem to be working for me…? what do you get?

---

<div class="post-metadata">

### Author: ![davesnx](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/davesnx/32/2949_2.png) [@davesnx](https://discuss.ocaml.org/u/davesnx)
#### Post date: [October 6, 2021, 6:25pm UTC](https://discuss.ocaml.org/t/ann-release-of-odoc-2-0-0/8582/5 "2021-10-06T18:25:19Z")

</div>

Weird, using curl I got a 404 and in the browser, I got 500.

```bash
curl -sI https://v3.ocaml.org/p/brr/0.0.1/doc/ffi_manual.html
HTTP/1.1 404 Not Found
Server: nginx/1.21.1
Date: Wed, 06 Oct 2021 18:23:33 GMT
Content-Type: text/html; charset=utf-8
Content-Length: 75619
Connection: keep-alive

```

Chrome:

```auto
This page isn’t working v3.ocaml.org is currently unable to handle this request.
HTTP ERROR 500

```

EDIT: Alright, It’s def not related with odoc 2.0, but more with the v3 website and my chrome. Works perfectly in Firefox and/or my phone. Sorry for the trouble!

---

<div class="post-metadata">

### Author: ![jonludlam](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/jonludlam/32/101_2.png) [@jonludlam](https://discuss.ocaml.org/u/jonludlam)
#### Post date: [October 6, 2021, 6:29pm UTC](https://discuss.ocaml.org/t/ann-release-of-odoc-2-0-0/8582/6 "2021-10-06T18:29:21Z")

</div>

Hum, working for me in Chrome, Safari and Firefox, but I do get the same `404` with curl. Well I’m just going to take this opportunity to point out that [v3.ocaml.org](https://v3.ocaml.org) is also looking for contributors and bugfixers 😉

---

<div class="post-metadata">

### Author: ![Maelan](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/maelan/32/1184_2.png) [@Maelan](https://discuss.ocaml.org/u/Maelan)
#### Post date: [October 6, 2021, 6:46pm UTC](https://discuss.ocaml.org/t/ann-release-of-odoc-2-0-0/8582/7 "2021-10-06T18:46:53Z")

</div>

All of this is awesome, thanks for all the hard work!

> [@jonludlam](#):
>
> The upshot of this is that there should never be any more odd double underscores leaking into your docs!

> [@jonludlam](#):
>
> Included in `odoc 2.0` are renderers for HTML and man pages

Yay!

---

<div class="post-metadata">

### Author: ![shonfeder](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/shonfeder/32/424_2.png) [@shonfeder](https://discuss.ocaml.org/u/shonfeder)
#### Post date: [October 6, 2021, 11:12pm UTC](https://discuss.ocaml.org/t/ann-release-of-odoc-2-0-0/8582/8 "2021-10-06T23:12:14Z")

</div>

Congrats and many thanks to all involved! This is wonderful 🙂

FYI: in Firefox on my iPhone the pages do not legibly:

 ![image](https://us1.discourse-cdn.com/flex020/uploads/ocaml/original/2X/b/b72eb64a099f4330a67c5a9da60136ef5cee2671.jpeg)

This is from the first link: [Bigbuffer (odoc.core\_kernel.Core\_kernel.Bigbuffer)](https://ocaml-doc.github.io/odoc-examples/core_kernel/Core_kernel/Bigbuffer/index.html)

---

<div class="post-metadata">

### Author: ![jonludlam](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/jonludlam/32/101_2.png) [@jonludlam](https://discuss.ocaml.org/u/jonludlam)
#### Post date: [October 6, 2021, 11:48pm UTC](https://discuss.ocaml.org/t/ann-release-of-odoc-2-0-0/8582/9 "2021-10-06T23:48:59Z")

</div>

Responsiveness is one of the things that [v3.ocaml.org](https://v3.ocaml.org/) does rather a lot better than the stock odoc css - take a look at [the equivalent page](https://v3.ocaml.org/p/core_kernel/v0.14.2/doc/Core_kernel/Bigbuffer/index.html).

We’ve also got some work planned to improve the layout of long module types and types - see [here](https://github.com/ocaml/odoc/issues/565) - current roadmap [here](https://github.com/ocaml/odoc/wiki/Roadmap), and I think it’s likely we’ll be thinking about responsiveness when handling that, so I expect that odoc 2.1 will make the output much more iphone friendly.

---

<div class="post-metadata">

### Author: ![shonfeder](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/shonfeder/32/424_2.png) [@shonfeder](https://discuss.ocaml.org/u/shonfeder)
#### Post date: [October 7, 2021, 2:41am UTC](https://discuss.ocaml.org/t/ann-release-of-odoc-2-0-0/8582/10 "2021-10-07T02:41:40Z")

</div>

Yes, the [v3.ocaml.org](http://v3.ocaml.org) looks beautiful on mobile and desktop!

---

<div class="post-metadata">

### Author: ![sid](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/sid/32/1476_2.png) [@sid](https://discuss.ocaml.org/u/sid)
#### Post date: [October 7, 2021, 5:59am UTC](https://discuss.ocaml.org/t/ann-release-of-odoc-2-0-0/8582/11 "2021-10-07T05:59:36Z")

</div>

I am noticing something on [Core\_kernel.Bigbuffer · core\_kernel v0.14.2 · OCaml Packages](https://v3.ocaml.org/p/core_kernel/v0.14.2/doc/Core_kernel/Bigbuffer/index.html) – look at the part where it says “include Base.Buffer.S”. In the iphone version screenshot post (ignore, for now, the lack of responsiveness) you can see that around the arrow is a kind of “tab” that shows the extent of the items brought in by the signature inclusion. This is useful because an include can bring in many items.

This visual device is _not_ present on the v3.ocaml page. Is this a theming issue – that they simply disabled the tab that shows which items are coming with a `include`?

---

<div class="post-metadata">

### Author: ![jonludlam](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/jonludlam/32/101_2.png) [@jonludlam](https://discuss.ocaml.org/u/jonludlam)
#### Post date: [October 7, 2021, 7:19am UTC](https://discuss.ocaml.org/t/ann-release-of-odoc-2-0-0/8582/12 "2021-10-07T07:19:31Z")

</div>

It’s a CSS issue - tracked [here](https://github.com/ocaml/v3.ocaml.org-server/issues/54). “Good first issue”, hint hint! 😃

---

<div class="post-metadata">

### Author: ![Lortex](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/lortex/32/2607_2.png) [@Lortex](https://discuss.ocaml.org/u/Lortex)
#### Post date: [October 7, 2021, 2:58pm UTC](https://discuss.ocaml.org/t/ann-release-of-odoc-2-0-0/8582/13 "2021-10-07T14:58:33Z")

</div>

> Weird, using curl I got a 404 and in the browser, I got 500.

For the curl error, we’ve just found out that `HEAD` http requests are not properly handled. So thank you for spotting this !

An issue has been created for this: [HEAD requests yield 404s · Issue #148 · ocaml/ocaml.org · GitHub](https://github.com/ocaml/v3.ocaml.org-server/issues/148)

---

<div class="post-metadata">

### Author: ![sid](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/sid/32/1476_2.png) [@sid](https://discuss.ocaml.org/u/sid)
#### Post date: [October 10, 2021, 5:55am UTC](https://discuss.ocaml.org/t/ann-release-of-odoc-2-0-0/8582/14 "2021-10-10T05:55:31Z")

</div>

The documentation provided by Rust’s `cargo doc` gives you a search bar in your browser. This feature is implemented in the client frontend rather than backend by sending the search index as a json object. This avoid having to package a server backend with the docs.

There seems to be some discussion about providing a similar feature [here](https://github.com/ocaml/odoc/issues/567) but nothing much subsequently. I was curious if that had been more conversation subsequently.

Even a basic ability to fuzzy search a function name or type name would be useful.

---

<div class="post-metadata">

### Author: ![Gopiandcode](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/gopiandcode/32/5346_2.png) [@Gopiandcode](https://discuss.ocaml.org/u/Gopiandcode)
#### Post date: [October 11, 2021, 8:31am UTC](https://discuss.ocaml.org/t/ann-release-of-odoc-2-0-0/8582/15 "2021-10-11T08:31:00Z")

</div>

> [@sid](#):
>
> There seems to be some discussion about providing a similar feature [here](https://github.com/ocaml/odoc/issues/567) but nothing much subsequently. I was curious if that had been more conversation subsequently.

If you decide to go the way of using a bloom filter for the search index, then, FYI, there’s a fully verified implementation of a bloom filter here: [GitHub - verse-lab/ceramist: Verified hash-based AMQ structures in Coq](https://github.com/certichain/ceramist) 🙂

Disclaimer: I’ve never actually tried running it.

---

<div class="post-metadata">

### Author: ![jonludlam](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/jonludlam/32/101_2.png) [@jonludlam](https://discuss.ocaml.org/u/jonludlam)
#### Post date: [October 11, 2021, 8:53am UTC](https://discuss.ocaml.org/t/ann-release-of-odoc-2-0-0/8582/16 "2021-10-11T08:53:41Z")

</div>

That particular issue is on the [roadmap](https://github.com/ocaml/odoc/wiki/Roadmap) for 2.2. Search is definitely something we want to implement. The question of whether it’s client-side or server-side is something to consider carefully, and I think we’ll likely need some real-world experience before deciding. Certainly for [v3.ocaml.org](http://v3.ocaml.org) it seems unlikely that we’ll be able to implement search across all packages/versions client-side only!

---

<div class="post-metadata">

### Author: ![davesnx](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/davesnx/32/2949_2.png) [@davesnx](https://discuss.ocaml.org/u/davesnx)
#### Post date: [February 1, 2022, 4:33pm UTC](https://discuss.ocaml.org/t/ann-release-of-odoc-2-0-0/8582/17 "2022-02-01T16:33:38Z")

</div>

Remember Jordan was fighting for that particular problem when they wanted to unify esy.sh, [reason-native.com](http://reason-native.com), reason-react docs.

He came up with [GitHub - jordwalke/paradoc: One Click Docs](https://github.com/jordwalke/paradoc) with a mention to [GitHub - jordwalke/paradoc: One Click Docs](https://github.com/jordwalke/paradoc#search-features).

If I can suggest something I will try to push for a client-side and if that doesn’t workout can try a 3rd party with algolia. Their doc search is quite powerful. The basic reasoning behind this are a bunch of nice details: possibility for an offline search, translatable-friendly, way simpler to implement (IMHO).

---

<div class="post-metadata">

### Author: ![lindig](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/lindig/32/532_2.png) [@lindig](https://discuss.ocaml.org/u/lindig)
#### Post date: [February 6, 2022, 1:42pm UTC](https://discuss.ocaml.org/t/ann-release-of-odoc-2-0-0/8582/18 "2022-02-06T13:42:48Z")

</div>

The [odoc documentation](https://ocaml.github.io/odoc/) refers to the OCaml manual and lists the [differences](https://ocaml.github.io/odoc/ocamldoc_differences.html) to OCaml. If we want odoc to become the new standard, I think a self-contained documentation would be helpful. I also think the format documentation should be at the center of the documentation and all other aspects should be secondary.
