# Visualizing dependencies between Ocaml modules

**URL:** <https://discuss.ocaml.org/t/visualizing-dependencies-between-ocaml-modules/15254>\
**Category:** Ecosystem\
**Created:** [September 6, 2024, 10:14am UTC](https://discuss.ocaml.org/t/visualizing-dependencies-between-ocaml-modules/15254 "2024-09-06T10:14:56Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![Picasso](https://avatars.discourse-cdn.com/v4/letter/p/e19b73/32.png) [@Picasso](https://discuss.ocaml.org/u/Picasso)\
**Post date:** [September 6, 2024, 10:14am UTC](https://discuss.ocaml.org/t/visualizing-dependencies-between-ocaml-modules/15254/1 "2024-09-06T10:14:56Z")

</div>

Hi,

I am trying to understand a (more or less large) Ocaml project with lot of files and modules.  
I am particularly interested, as a first step, in understanding the interfaces theses modules expose and how theses interfaces are used. I believe an UML component diagram would help with this.

My question is : Is there any tool that can generate the component diagram from Ocaml code?  
I have in the past worked with a tool called Moose ([http://moosetechnology.org/](http://moosetechnology.org/)) that not only generates visualization of OO source code but also allows one to make queries and interact with diagrams to navigate specific aspects of the code. I wonder if such a tool exists for Ocaml (or more broadly, functional) code.

---

<div class="post-metadata">

**Author:** ![reynir](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/reynir/32/6496_2.png) [@reynir](https://discuss.ocaml.org/u/reynir)\
**Post date:** [September 6, 2024, 11:02am UTC](https://discuss.ocaml.org/t/visualizing-dependencies-between-ocaml-modules/15254/2 "2024-09-06T11:02:56Z")

</div>

I have two answers that are likely not quite what you asked for, but I hope you find them relevant regardless.

At Robur we use [opam-graph](https://git.robur.coop/robur/opam-graph) to generate visualizations for dependencies at opam package level. You can look at an example for this build (the top visualization): [https://builds.robur.coop/job/opam-graph/build/f4823163-eaae-4ce1-9bd2-60261f930392](https://builds.robur.coop/job/opam-graph/build/f4823163-eaae-4ce1-9bd2-60261f930392)

We also use [modulectomy](https://github.com/robur-coop/modulectomy) (or rather a fork) originally created by @Drup to visualize OCaml binary size as contributed by different OCaml modules. See for example the second visualization here: [Job miragevpn-server 2024-09-05 15:27:23Z](https://builds.robur.coop/job/miragevpn-server/build/cd4bf9b1-2f99-4359-9102-f85d9981119b)

---

<div class="post-metadata">

**Author:** ![sim642](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/sim642/32/3597_2.png) [@sim642](https://discuss.ocaml.org/u/sim642)\
**Post date:** [September 6, 2024, 6:09pm UTC](https://discuss.ocaml.org/t/visualizing-dependencies-between-ocaml-modules/15254/3 "2024-09-06T18:09:31Z")

</div>

I’ll use this opportunity to plug my own tool: [GitHub - sim642/odep: Dependency graphs for OCaml modules, libraries and packages](https://github.com/sim642/odep). It can do visualizations at various levels: dune modules, findlib libraries and opam packages.  
At the end of odep’s README I have a list of various other tools I’ve found and how they differ.

---

<div class="post-metadata">

**Author:** ![Drup](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/drup/32/35_2.png) [@Drup](https://discuss.ocaml.org/u/Drup)\
**Post date:** [October 1, 2024, 8:42am UTC](https://discuss.ocaml.org/t/visualizing-dependencies-between-ocaml-modules/15254/4 "2024-10-01T08:42:17Z")

</div>

This post really drives the point home that I’m a bad maintainer, all my funky weird experiments end up adopted and maintained by someone else 😅

@sim642 Well done, that tool looks amazing !  
@reynir Maybe we should do some github shenanigans to make your repository the main one. 🙂

---

<div class="post-metadata">

**Author:** ![user1](https://avatars.discourse-cdn.com/v4/letter/u/5daacb/32.png) [@user1](https://discuss.ocaml.org/u/user1)\
**Post date:** [December 1, 2024, 12:18pm UTC](https://discuss.ocaml.org/t/visualizing-dependencies-between-ocaml-modules/15254/5 "2024-12-01T12:18:12Z")

</div>

Your tool looks great @sim642 !  
I could not find the explanations for the generated graphs. In particular,

- what does it mean when a node is grey? (is a node grey if and only if it is in a “foreign” package ?)
- what does it mean when a node has lozenge shape ? (is a node a lozenge if and only if it is an executable ?)
- what does it mean when a node has rectangle or ellipse shape ?

Also, is it correct that the graph only shows the “transitive core” of the dependency relation (that is, if A depends on B and also explicitly on C, and B depends on C, then the arrow from A to C is not displayed) ? Is there (a project of) an option to display all explicit dependencies, even the ones deducible by transitivity ? (note that this is included, but need not be, the transitive closure of the above)

---

<div class="post-metadata">

**Author:** ![sim642](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/sim642/32/3597_2.png) [@sim642](https://discuss.ocaml.org/u/sim642)\
**Post date:** [December 1, 2024, 5:40pm UTC](https://discuss.ocaml.org/t/visualizing-dependencies-between-ocaml-modules/15254/6 "2024-12-01T17:40:09Z")

</div>

Indeed, I haven’t provided documentation about the output, but here are the answers to your questions:

1. Gray ellipses are (findlib) libraries outside the current dune project (if using the dune mode).
2. White diamonds are dune executables.
3. White ellipses are dune libraries in the current dune project.
4. White rectangles can be one of two things:
  1. (opam) packages if they include a version number (in the findlib graph, they surround libraries).
  2. (OCaml) modules otherwise (in the dune graph, they are surrounded by a rectangle that also indicates the cluster corresponding to one library).

5. Yes, by default it computes the [transitive reduction](https://en.wikipedia.org/wiki/Transitive_reduction) to keep the graphs easier to look at (and faster to render by Graphviz). Depending on the graph, you can use `--tred-modules=false` or `--tred-libraries=false` to disable the reduction.
