A template for a cross-platform CLI with CI support

I’m looking for a Ocaml template to build a CLI tool that fulfils the following list of requirements:

  • Includes github actions files for compiling and uploading generated assets
  • Builds versions for MacOS and Linux
  • Reason syntax (additionally to ML one)
  • Has a way to install it easily. Ideally just downloading a binary, but if there are more requirements a one command install script is fine
  • Does not depend on libraries installed globally on my system, nor requires me to install libs globally (this includes development)

It will be ideal to be able to compile it using something like cosmpolitan, but if I understand it correctly it has several limitations in terms of which libraries can be used, specially those that use C bindings.

The libs I like to use for this kind of tools are CMDLiner, some kind of shell wrapper, a TUI library like NottUI and some kind of future Monad like LWT or friends.

Normally I will jus try to use hello-reason, because I like what esy promises and it’s easy to understand. However, it is focused on publishing to NPM, they only have complete pipelines for Azure pipelines and I already tried to bend it to my needs in terms of compilation and distribution and I failed.

The kind of tools that I want to build with this, for example, are a dotfiles manager for my personal stuff, helpers for my day-to day cli needs, ways to automate repetitive tasks, etc, so portability is key here, as it is the ability to start a project very quick and iterate on it, and not spend whole days trying to make it compile.


I think that is the most complicated requirement. Recently, Melange support has been added to dune, and you should check does it suite you.

I think everything else could be assembled using github actions’ recipes.

If we’re talking of a “native” project (build to a native binary using ocamlopt), using reason syntax is supported by dune directly. Just name your source files .re / .rei instead of .ml / .mli, add a dependency on refmt and you’re good to go.

1 Like

Thanks, I didn’t know about that!

Yes, that is the easiest par of the entire list :smile:

You could try Spin with this template: GitHub - ocaml-templates/spin-reason-cli: Spin generator for CLI with Reason and Esy support.. I think it checks all of your requirements.

1 Like

You may be interested in bob which uses esperanto (which uses cosmopolitan under the hood) for portable (Windows, macOS, Linux, BSD) binaries. The binary is built and uploaded by an GitHub action.

I saw bob in the past, and indeed it looks a lot like what I want. Do you think it will be hard to completely adapt it to become another project?

I thought Spin has moved away from reason. Will take a look at it, thanks

I look at it with more detail, and indeed I saw it on the past. In fact, I think I used it.
The problem it has is that it builds, then formats and finally runs tests, but it does not have any way to extract the generated build artifacts and upload them to a release, which is where I always stuck when I have to build things with esy using github actions.

Spin itself used to do something similar. You might find spin/release.yml at main · tmattio/spin · GitHub and spin/install.sh at main · tmattio/spin · GitHub useful and you should be able to copy them without having to do too many changes.

I’m curious though, if it’s for your personal use, why not compile locally and run dune install?

That is a fair question. I have several reasons that I will try to summarize.
First and foremost, is that I don’t want to invest and get in love with an ecosystem that will not allow me to deploy to someone else’s computer easily.
One simple example would be to build neovim plugins, I want people to use them easily without having to install an entire ocaml tool chain.

I also want this tool (or a separate one) be part of my computer initial setup process, and I don’t want to have to setup ocaml dev environment first. Specially if I am on a little VM or on a remote low power computer.

Also, one use case I have for this little tools is to help my wife with little repetitive tasks for her work, and I can ask her to setup ocaml on her laptop just to run my tool.

Hope that makes sense

I see your point, I do have a few cli tools that I want to have available precompiled. One of them is public, doi2bib: it is a cli, with ci tests, and generation of precompiled binaries on release (including windows, linux statically compiled and mac x86_64).

It is far from perfect: on mac you need to install libgmp via homebrew or macports, and I cannot yet generate mac arm64 binaries automatically, but it has been working fine for me so far.

I don’t know if this is the kind of template you are looking for, but you can have a look.


You may also want to look at dkml-workflows-regular-example. It was tailor-made for distributing binaries across platforms. @mseri’s approach is based on setup-ocaml which is often the right choice, but it has its own advantages and disadvantages. There is a comparison matrix at dkml-workflows that can help you decide, and it also has onboarding instructions.

Both belong in the Package Management | OCamlverse directory; I opened a PR to add dkml-workflows (aka. setup-dkml) to it.


That looks super interesting, and it even has a step by step tutorial. I’ll give it a go, thanks