# Plugin-system for OCaml programs

**URL:** <https://discuss.ocaml.org/t/plugin-system-for-ocaml-programs/9048>\
**Category:** Learning\
**Tags:** language\
**Created:** [December 22, 2021, 6:34am UTC](https://discuss.ocaml.org/t/plugin-system-for-ocaml-programs/9048 "2021-12-22T06:34:25Z")\
**Posts on this page:** 11\
**Page:** 1

<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:** [December 22, 2021, 6:34am UTC](https://discuss.ocaml.org/t/plugin-system-for-ocaml-programs/9048/1 "2021-12-22T06:34:25Z")

</div>

One common functionality that I’ve found myself wanting to incorporate into applications that I build is the support for user-defined plugins/extensions (without having to re-compile the application itself), but I don’t know _what is the recommended way of providing a plugin system for OCaml programs_?

Now obviously one approach would be to define an extension language and include a parser/interpreter as part of the application, but this is a hassle, and introduces the additional burden of having to provide language support/documentation.

Is there a clean interface for using OCaml itself as an extension language? i.e the user writes OCaml code, compiles it to bytecode/native-object-code, and then loads it into the main OCaml program? Are there any good examples of this being done in the wild?

---

<div class="post-metadata">

**Author:** ![Chet\_Murthy](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/chet_murthy/32/1501_2.png) [@Chet\_Murthy](https://discuss.ocaml.org/u/Chet_Murthy)\
**Post date:** [December 22, 2021, 7:21am UTC](https://discuss.ocaml.org/t/plugin-system-for-ocaml-programs/9048/2 "2021-12-22T07:21:31Z")

</div>

Is it allowed to re-link the application?

---

<div class="post-metadata">

**Author:** ![orbitz](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/orbitz/32/110_2.png) [@orbitz](https://discuss.ocaml.org/u/orbitz)\
**Post date:** [December 22, 2021, 7:50am UTC](https://discuss.ocaml.org/t/plugin-system-for-ocaml-programs/9048/3 "2021-12-22T07:50:29Z")

</div>

Depends on your requirements, but personally I generally prefer plugins to be separate executables that use IPC. It is better security and lets users write plugins in any language. The downsides is you have to define a protocol over IPC (lots of options available) and maybe it’s too heavy weight for what you want to do.

---

<div class="post-metadata">

**Author:** ![nojb](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/nojb/32/519_2.png) [@nojb](https://discuss.ocaml.org/u/nojb)\
**Post date:** [December 22, 2021, 8:25am UTC](https://discuss.ocaml.org/t/plugin-system-for-ocaml-programs/9048/4 "2021-12-22T08:25:00Z")

</div>

I don’t know of any good example in the wild.

The basic tool is [`Dynlink`](https://ocaml.org/api/Dynlink.html) which allows to load OCaml code at runtime and link it into the main program. The plugin is supposed to “register” itself with the main program at initialization time, as the main program has no way to directly call into the plugin code.

`Dynlink` is pretty bare bones and you may prefer a higher-level interface built on top of it. I have never used it but there is [GitHub - janestreet/ocaml\_plugin: Automatically build and dynlink ocaml source files](https://github.com/janestreet/ocaml_plugin) along these lines.

A tricky point is how to deal with dependencies among plugins (in the case where plugins can depend on each other). For that there is `findlib.dynlink`, and Dune offers a higher-level (experimental) interface called “sites”, see [How to load additional files at runtime — dune documentation](https://dune.readthedocs.io/en/stable/sites.html#plugins-and-dynamic-loading-of-packages).

Cheers,  
Nicolas

---

<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:** [December 22, 2021, 9:18am UTC](https://discuss.ocaml.org/t/plugin-system-for-ocaml-programs/9048/5 "2021-12-22T09:18:19Z")

</div>

> [@Chet\_Murthy](#):
>
> Is it allowed to re-link the application?

The kind of picture I’m going for is that the user installs the application once, and then may extend the functionality by adding plugins on a per usage basis (probably via command line arguments).

> [@orbitz](#):
>
> Depends on your requirements, but personally I generally prefer plugins to be separate executables that use IPC.

Maybe, but this also makes sharing data between the main application and plugins to be a hassle, requiring the input to be serialised. Ideally I’d want to provide the user a module-signature interface that they can implement in OCaml however they want, rather than having to go through IPC.

---

<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:** [December 22, 2021, 9:19am UTC](https://discuss.ocaml.org/t/plugin-system-for-ocaml-programs/9048/6 "2021-12-22T09:19:45Z")

</div>

Perfect, thanks! This looks like what I was looking for. `ocaml_plugin` seems to load in the OCaml compiler as well for compiling source files which is useful, but I guess I can settle with just Dynlink. The dune-sites functionality seems interesting, I’ll need to have a look.

---

<div class="post-metadata">

**Author:** ![Chet\_Murthy](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/chet_murthy/32/1501_2.png) [@Chet\_Murthy](https://discuss.ocaml.org/u/Chet_Murthy)\
**Post date:** [December 22, 2021, 9:51am UTC](https://discuss.ocaml.org/t/plugin-system-for-ocaml-programs/9048/7 "2021-12-22T09:51:43Z")

</div>

What happened to `ocamlnat` ? Shouldn’t that have the necessaries to link native-code modules and deal with dependencies, etc ?

---

<div class="post-metadata">

**Author:** ![nojb](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/nojb/32/519_2.png) [@nojb](https://discuss.ocaml.org/u/nojb)\
**Post date:** [December 22, 2021, 10:29am UTC](https://discuss.ocaml.org/t/plugin-system-for-ocaml-programs/9048/8 "2021-12-22T10:29:27Z")

</div>

In general, toplevels (`ocaml` or `ocamlnat`) do not know anything about dependencies (that’s one of the reasons for having `findlib`). As for the ability to link native-code they work roughly the same as `Dynlink`.

Cheers,  
Nicolas

---

<div class="post-metadata">

**Author:** ![orbitz](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/orbitz/32/110_2.png) [@orbitz](https://discuss.ocaml.org/u/orbitz)\
**Post date:** [December 22, 2021, 10:30am UTC](https://discuss.ocaml.org/t/plugin-system-for-ocaml-programs/9048/9 "2021-12-22T10:30:35Z")

</div>

> [@Gopiandcode](#):
>
> Maybe, but this also makes sharing data between the main application and plugins to be a hassle, requiring the input to be serialised. Ideally I’d want to provide the user a module-signature interface that they can implement in OCaml however they want, rather than having to go through IPC.

What I’ve done is provides a little framework that does the IPC for them and then calls into a function they provide. And, arguably, making sharing data harder is a benefit to security. But I take your point that you’d prefer in-process plugin.

---

<div class="post-metadata">

**Author:** ![gndl](https://avatars.discourse-cdn.com/v4/letter/g/58f4c7/32.png) [@gndl](https://discuss.ocaml.org/u/gndl)\
**Post date:** [December 22, 2021, 6:01pm UTC](https://discuss.ocaml.org/t/plugin-system-for-ocaml-programs/9048/10 "2021-12-22T18:01:11Z")

</div>

As @nojb said, Dynlink is a suitable tool for this feature.  
If plugins need ad hoc polymorphism, the natural way is to use OOP (this is what I do in [Graffophone](https://github.com/gndl/graffophone/blob/main/src/pluginsManager.ml)). However, It may be possible to use [Kantian’s solution](https://discuss.ocaml.org/t/the-shape-design-problem/7810/8).

---

<div class="post-metadata">

**Author:** ![Chet\_Murthy](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/chet_murthy/32/1501_2.png) [@Chet\_Murthy](https://discuss.ocaml.org/u/Chet_Murthy)\
**Post date:** [December 22, 2021, 8:28pm UTC](https://discuss.ocaml.org/t/plugin-system-for-ocaml-programs/9048/11 "2021-12-22T20:28:53Z")

</div>

Fair enough: I’ve used findlib’s infrastructure to get dependency-order prereqs for a module, and it was no biggie.
