Hi all! It is my pleasure to announce a project I have been working on and using for some time.
Onix is a tool for building OCaml projects with Nix. Onix provides an alternative to opam and keeps full compatibility with opam repository and opam files.
Features
- Fully hermetic and deterministic builds based on a lock file. The lockfile includes precise package versions generated from your opam files, source hashes and the Git revision of the opam repository used to perform the resolution. See an example here.
- Robust cross-project cache powered by Nix store.
- Support for
pin-depends
to add packages outside of the opam repository (this can be used to test experimental packages or pull requests, for example). - Support for automated
depexts
installation from nixpkgs. - Conditional compilation of
with-test
,with-doc
andwith-dev-setup
dependencies. In particular to support local development workflows withocamlformat
,ocaml-lsp-server
, etc. - Support for compiler variants similar to opam (for example, the flambda compiler can be built).
- Compilation of locally vendored packages. I use this workflow to test patches to project dependencies before submitting PRs.
- Generation of opam-compatible “locked” files. This way any onix project can also be used directly with opam.
Motivation
On a more personal note, I started working on onix out of frustration with the existing tools like opam, esy, monorepo, opam2nix and opam-nix. Partially because the UX for working with local projects in a reproducible way is not great, and partially because I had a need to precisely manage system dependencies which is only possible with Nix. In the end, I decided to build something that is highly flexible and yet requires almost no Nix knowledge and (hopefully) is easy to use. Even though there are still some rough edges, I’m currently using onix in almost all of my OCaml projects.
Dune-compatibility and future work
I know there is work being done to include lock-file generation and source fetching in dune and I hope there will be a way to find compatibility between the onix lock format and the dune lock format. I do not think that this new direction in dune will eliminate the need for onix because dune will not manage system dependencies in the same deterministic way as Nix. For instance, in the Rust community there is an abundance of nix-based tools to work with Cargo’s lock-files. I’m very excited to see how dune solves this problem and want to keep onix in sync with this effort.
There are some other areas that I’d like to explore in the future that haven’t been a priority for me, namely:
- Adding support for cross-compilation (which already works for nix with @anmonteiro’s excellent GitHub - nix-ocaml/nix-overlays: OCaml-focused, custom nix-overlays).
- Improving support for flakes and “pure” project builds.
- Provide a Nix cache with pre-built opam packages.
- Create a simple CLI with commands like
onix lock
andonix shell
that fully abstract nix.
Final thoughts
Note that this release is not published on opam as currently the workflow is fully driven by Nix. So follow the instructions in the README if you would like to give onix a try. There is also a dedicated repository with examples to showcase more advanced use cases: GitHub - rizo/onix-examples.
Hope someone finds onix useful and happy to answer any questions.
Happy building!