Here are three reasons why I think you might want to use multilibs:
- Multiple packages that are versioned together
One good test is indeed “does it make sense to version these packages independently?”. Often in a multi-package project you have a situation like this:
- You only ever use and test the packages together at the exact same version (same commit). Therefore you never test other version combinations.
- You have no interest in e.g. using CPP to ensure that the packages are compatible with a range of the other packages.
- The packages are tightly coupled, e.g. each new version of A requires the features from the new version of B, etc.
In this case you often end up using the same version for everything and advancing them in lockstep because that reflects the reality of how the packages are supposed to be used. Merging them into a single package with multiple sublibs does the same thing much more cleanly.
Examples:
- HLS and its plugins
- amazonka
- Many industrial codebases I’ve seen
As a side note, if you can version things separately then it’s tempting to try and actually do it properly. I have seen people drive themselves a bit insane trying to properly follow PVP for many packages in the same repo (this is part of why we switched to lockstep versioning in HLS recently).
- Extra functionality that incurs more dependencies
Sometimes you want to expose just a little extra thing from your library, but that incurs a new dependency that you don’t want in the main library.
Examples
- Typeclass instances (for scale, try searching Hackage for “instances”)
- Test utility code
- Just little extras, e.g. the
lsp-types
package now has an extra public library that exposes the model used by the code generator, which isn’t even a dependency of the main library
At the moment you have to put such things in separate packages, which is quite annoying. With multiple public libraries you can just have the test-utility code in an additional library with extra deps.
Of course, in principle you might want to version these libraries separately. Maybe the Arbitrary
instances don’t change very often and work with many versions of the base package. But: probably nobody cares or would gain anything from the finer-grained versioning.
- Discoverability
In theory, it should be easier to discover a family of related libraries if they are packaged together. Consider again e.g. amazonka. Today the Hackage UI is not there, but in the future it would be nice to be able to pull up a package and go “oh, there’s also a library for quickcheck instances, that’s useful”.
I think some version of these conditions applies for a lot of packages.