# Dune/OPAM package layout with 'extension' sub-libraries?

**URL:** <https://discuss.ocaml.org/t/dune-opam-package-layout-with-extension-sub-libraries/3737>\
**Category:** Ecosystem\
**Tags:** package-design, opam, dune, library\
**Created:** [May 1, 2019, 3:50pm UTC](https://discuss.ocaml.org/t/dune-opam-package-layout-with-extension-sub-libraries/3737 "2019-05-01T15:50:45Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![MattWindsor91](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/mattwindsor91/32/1327_2.png) [@MattWindsor91](https://discuss.ocaml.org/u/MattWindsor91)\
**Post date:** [May 1, 2019, 3:50pm UTC](https://discuss.ocaml.org/t/dune-opam-package-layout-with-extension-sub-libraries/3737/1 "2019-05-01T15:50:45Z")

</div>

Hi all,

Suppose I’m making a package that has one _main_ library `L`, consisting of several different modules `L.Foo`, `L.Bar`, `L.Baz`, etc and with a certain set of dependencies; I then have a few smaller extension libraries `A`, `B`, and ‘C’, each with their _own_ modules and dependencies.

The concrete example here is that I’m re-architecting [travesty](https://github.com/MattWindsor91/travesty) such that the main library contains monadic traversals and other such things and depends only on `Base`, but there’ll also be satellite libraries that include extension overlays for adding those traversals to `Base` containers, to `Core_kernel` containers, and also building new containers such as zippers and whatnot. So, I have a `Travesty` library, a `Containers` library, a `Base_exts` one, and a `Core_kernel_exts` one.

(The `Core_kernel` container depends on `Core_kernel`, whereas the other libraries don’t, so there’s an actual dependency difference here—but working out how to do that properly in `opam` is another question for another day.)

Looking around, the usual idiom for multiple distinct but related libraries in one package is to `public-name` them `package-name.library-name` in the `dune` config, give them the top-level module and `name` of `library-name`, and then refer to them pretty much everywhere in code as `library-name`. So, I’d have `travesty.containers` as my `public-name`, `containers` as my `name`, and refer to, say, `'a Containers.Singleton.t`.

This would work nicely if the libraries were sufficiently coherent on their own to spin out into their own namespaces. But, in my case, they really are just satellites of my `Travesty` library, with names that make no sense outside of the `Travesty` context (and, worse, would pollute the namespace and clash with other libraries like `containers`!), and ideally I’d want to refer to them as `Travesty.Containers.Singleton.t` etc.

What would be the most idiomatic thing to do here? The way I’ve currently done it in `travesty`, which feels kind of horrible, is:

- `public-name` of `travesty.containers`
- `name` of `travesty_containers`
- if I’m importing it from somewhere else, it’ll be `Travesty_containers.Singleton.t`

Is there an easier way?

I suppose one thing I could do is make the `travesty` library an umbrella for all the other packages, containing the union of their dependencies and re-exporting things into their correct positions in the hierarchy. I’d then move what is currently in the `travesty` library to, say, `travesty.common`. This seems a bit baroque, though, and, unless there’s some `opam` magic that means that it can switch off re-exports of the `core_kernel` extensions unless `core_kernel` is present, it’ll make using the more minimal fragments of the library somewhat unpleasant.

---

<div class="post-metadata">

**Author:** ![jeremiedimino](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/jeremiedimino/32/699_2.png) [@jeremiedimino](https://discuss.ocaml.org/u/jeremiedimino)\
**Post date:** [May 2, 2019, 7:35am UTC](https://discuss.ocaml.org/t/dune-opam-package-layout-with-extension-sub-libraries/3737/2 "2019-05-02T07:35:02Z")

</div>

If you disable warning 49, you can write `module Containers = Travesty_containers` in the umbrella `travesty.ml` file without declaring a dependency on `travesty.containers` . Though, I personally wouldn’t recommend doing this sort of things. In the long run, it might cause more troubles than it helps.

---

<div class="post-metadata">

**Author:** ![MattWindsor91](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/mattwindsor91/32/1327_2.png) [@MattWindsor91](https://discuss.ocaml.org/u/MattWindsor91)\
**Post date:** [May 9, 2019, 2:16pm UTC](https://discuss.ocaml.org/t/dune-opam-package-layout-with-extension-sub-libraries/3737/3 "2019-05-09T14:16:55Z")

</div>

Yeah, I’d rather avoid anything that heavyweight 😅 I’ll probably just keep as-is for now; the library’s in a pretty heavy state of breakable change flux anyway, so it’s probably ok if I get it sub-optimal to begin with.
