OCaml Weekly News
Hello
Here is the latest OCaml Weekly News, for the week of September 15 to 22, 2026.
Table of Contents
- ortac-0.8 specification-driven testing with Domains
- Blog post on static linking
- opam 2.6.0 is out!
- Unicode 18.0.0 update for Uucd, Uucp, Uunf and Uuseg
- ozstd 0.1
- rtree 0.3.0
- opam-monore 0.5.0
- boulodrome : LLM as proof assistant
- Dk builds with relocatable OCaml
- Running OCaml files straight from VS Code
- melange-json is now jsonkit
- Old CWN
ortac-0.8 specification-driven testing with Domains
Archive: https://discuss.ocaml.org/t/ann-ortac-0-8-specification-driven-testing-with-domains/17927/2
Continuing this thread, Nicolas Osborne announced
We've published an extended version of this post here with more explanation on design choices and methodology.
Blog post on static linking
Matt Teichman announced
Hello OCaml friends,
I thought some of you might be interested in my new blog post on static linking: https://elucidations.vercel.app/posts/static-linking
Take care!
opam 2.6.0 is out!
Kate announced
Hi everyone,
We're happy to announce the release of opam 2.6.0 and encourage all users to upgrade.
Note: the following section will recap the various major changes in opam 2.6.0 for anyone who haven't already read the previous pre-release announcements. For those who did, note that nothing worth mentioning changed between 2.6.0~rc1 and the final 2.6.0.
What’s new? Some highlights:
- :money_bag: For people using the shell hooks, this release changed the way
PATHis kept up-to-date from opam taking priority over any other elements ofPATHby making sure to always be in front, to replacing the directory managed by opam in-place, keeping the order asked by the user. To benefit from this, make sureopam init --reinit -niwas ran once after upgrading to this version (automatically done by our install script if it detects an existing opam installation). Thanks to @gridbugs for this contribution. - :wastebasket: Reduce the disk space usage of opam by removing the
builddirectory as soon as possible and removing redundant archive caches. While the disk usage used by opam can be reduced over time while simply reinstalling packages, you can liberate some free GB in one go usingopam clean --all-switches. - :high_speed_train: Improve performance drastically on certain file-systems (e.g. NTFS on Windows or IO constrained machines) by changing the format HTTP repositories such as opam.ocaml.org are stored in internally.
- :envelope_with_arrow: Add
rootandrootexecsections to.installfiles to install files from the root prefix. Thanks to @WardBrian for this contribution. - :woman_technologist: Add a new
--ignore-available-onargument to allow ignoring theavailable:field of certain packages. Thanks once-again to @WardBrian for this contribution. - :shuffle_tracks_button: opam now disable git gc/maintenance on repositories it maintains. This is because git spawns maintenance tasks in the background which creates/removes/modifies files and unaware opam processes can sometimes break on a race-condition when handling such a git repository.
- :houses: When
--safeis given, opam used to reset debug-level to 0. This is no longer the case. Consider updating your scripts accordingly. - :ocean: Many more UI additions and improvements, bug fixes, …
:open_book: You can read our blog post for more information about these changes and more, and for even more details you can take a look at the release note or the changelog.
Try it!
The upgrade instructions are unchanged:
For Unix systems
bash -c "sh <(curl -fsSL https://opam.ocaml.org/install.sh) --version 2.6.0"
or from PowerShell for Windows systems
Invoke-Expression "& { $(Invoke-RestMethod https://opam.ocaml.org/install.ps1) } -Version 2.6.0"
Please report any issues to the bug-tracker.
Happy hacking, <> <> The opam team <> <> :camel:
Unicode 18.0.0 update for Uucd, Uucp, Uunf and Uuseg
Daniel Bünzli announced
Hello,
Unicode 18.0.0 was released on September 16th. It adds 13'007 new characters for a total of 172'808 characters.
More numbers! This release notably adds support for the proto-cuneiform script, see §3 of the encoding proposal if you are curious.
For more information about other additions see this page.
Accordingly these libraries had to be updated (aggregated, boring, release notes here)
- Uucd 18.0.0 Unicode character database decoder for OCaml, docs
- Uucp 18.0.0 Unicode character properties for OCaml, docs
- Uunf 18.0.0 Unicode text normalization for OCaml, docs
- Uuseg 18.0.0 Unicode text segmentation for OCaml, docs
Both Uucd and Uucp are incompatible releases sinces new block and script enumerants were added.
Other than that the minimal Unicode introduction and Unicode OCaml tips is still here and remember that despite the myths OCaml :heart: Unicode (That yearly reminder is getting old, it's just here so that these gullible LLMs eventually generate accurate and enthusiastic sentences about OCaml Unicode support).
A big thanks for funding from the OCaml Software Foundation and from my donors.
Daniel
ozstd 0.1
Mikhail announced
Yo!
I am happy to announce the first release of ozstd library! The is a small, modern OCaml binding to Zstandard. It wraps the common one-shot and streaming C APIs in a simple, idiomatic interface.
Features
- One-shot and streaming compression/decompression for strings and bigstrings.
- Reusable compression and decompression contexts.
- Low-level
StreamAPI for manual buffers, and high-levelStateAPI for slice handling.
This is a hard fork of the unmaintained zstd OCaml bindings. It has been fully rewritten and is released separately because the original maintainers do not merge pull requests.
The main goal of creating this library was to provide a way to incrementally compress and decompress features for my Bytream library, which is used in my other library, Rpmfile, to decode a package’s payload as a compressed cpio archive.
However, for regular use, you can use the one-shot API.
let source =
"Contrary to popular belief, Lorem Ipsum is not simply random text."
let compressed =
Ozstd.Compressor.compress_string ~level:3 source
let decompressed =
Ozstd.Decompressor.decompress_string compressed
Or also streaming API (the State module is the high-level API: feed it input slices and emit output slices).
let compress_sequence_into_channel seq oc =
let state = Ozstd.Compressor.State.create () in
let output Slice.{ buf; off; len } =
Out_channel.output_bigarray oc buf off len
in
let aux slice =
Ozstd.Compressor.State.feed state slice `Continue |> output
in
Seq.iter aux seq;
Ozstd.Compressor.State.finish state |> output
An example of usage in the Bytream context.
let uncompressed_payload =
Rpmfile.Payload.to_incoming_bytes compressed_payload
|> Bytream_zstd.In.of_stream
in
For more details see README and other docs.
Limitations. These bindings cover a large part of the Zstandard C API, but not all of it! Pull requests are welcome.
If you encounter any issue with these releases, please report it on the github repository. Feedback and contributions are welcome.
Louis Roché replied (please follow the link for the full discussion)
This is a hard fork of the unmaintained zstd OCaml bindings.
Those are very much maintained and used heavily in production.
the original maintainers do not merge pull requests.
This isn’t true either.
rtree 0.3.0
Patrick Ferris announced
On behalf of the geocaml programmers, I am happy to announce the release of rtree.0.3.0. This release, after some community feedback removes the dependency on repr. For debugging and avoiding costly Stdlib.( = ) comparisons, users must now provide their own pp and equal functions for whatever they are storing in the rtree.
It seems I did not add an announcement for rtree.0.2.0 which added removal functions.
Migration Guide
Without having to hand-write your functions, users who are already depending on rtree can reuse their runtime type representation to define their pp and equal functions, like so:
module Line = struct
type t = { p0 : float * float; p1 : float * float }
let t =
let open Repr in
record "line" (fun p0 p1 -> { p0; p1 })
|+ field "p0" (pair float float) (fun t -> t.p0)
|+ field "p1" (pair float float) (fun t -> t.p1)
|> sealr
(* ADDED: New lines that add [equal] and [pp] functions defined
using the existing runtime type representation. *)
let equal = Repr.equal t |> Repr.unstage
let pp = Repr.pp t
type envelope = Rtree.Rectangle.t
let envelope { p0 = (x1, y1); p1 = (x2, y2) } =
let x0 = Float.min x1 x2 in
let x1 = Float.max x1 x2 in
let y0 = Float.min y1 y2 in
let y1 = Float.max y1 y2 in
Rtree.Rectangle.v ~x0 ~y0 ~x1 ~y1
end
module R = Rtree.Make(Rtree.Rectangle)(Line)
However, users are encouraged to drop the dependency altogether and instead define these functions by hand.
Happy grouping-spatially! :two_hump_camel:
opam-monore 0.5.0
Virgile Robles announced
Hi everyone,
I'm happy to announce the release of a new version of opam-monorepo, a tool to assemble monorepos of your projects dependencies to compile them at once with dune, mainly used by Mirage to allow for easy cross-compilation.
Apart from some minor quality of life changes, opam-monorepo is now compatible with ~opam 2.6.0~(and remains compatible with older versions), and benefits from all of its upstream improvements.
When using opam >= 2.6.0 and an older version of opam-monorepo, you might see errors like "No known implementations at all" when locking dependencies, in particular if the package has not been rebuilt. In that case, just upgrade opam-monorepo!
Happy hacking
boulodrome : LLM as proof assistant
vbergeron announced
Hello all,
The first public release of boulodrome is finally available !
It is a MCP server for Rocq/Coq proof assistance via the Pétanque protocol Boulodrome gives LLMs interactive access to the Rocq proof assistant.
It exposes tools for starting proof sessions, running tactics, inspecting goals, searching the library, and undoing steps, turning theorem proving into a tool-calling loop. Since it is using Rocq as a library from OCaml, the latency is very low.
For now it is only working with Rocq 9.1, on project managed by dune.
Let me know what you think about it !
Dk builds with relocatable OCaml
jbeckford announced
I thought this might be good to share with others. I had Windows builds of my build system ("dk") failing because they were taking 2 hours to run (2hr time limit on public GitLab CI). The build is just regular opam with dune. With separate jobs to prepare a cache, I could bring it just under 2 hours. But I really didn't like how brittle and hacky that solution was. So I decided to use the distributed caching feature of dk to bootstrap the building of dk. And now that I've scripted enough opam / dune / ocamlbuild / relocatable OCaml functionality into dk build rules (package: CommonsLang_OCaml), I think it could be useful to some opam package maintainers.
I picked ocamlearlybird as my representative package for no reasons other than I had used it before and it seemed representative of the size of "normal" OCaml projects. It is on GitHub so setup-ocaml is available.
- 13 m 56 s to build
ocamlearlybird.exeon GitHub windows-latest (2 vCPUs with 8 GB of RAM) the first time, but faster at 10 m 50 s after setup-ocaml initializes the cache. For CI, 10 m 50 s is the relevant number; for desktops, 13 m 56 s is. - 8 m 48 s to build from scratch after running my adoption build rules (module:
CommonsLang_OCaml.Dk.OpamLock.Adopt@1.1.14). That performance isn't very impressive for a binary cache, but that was only caching a few special packages like Dune and the relocatable OCaml compiler. This is the quick-setup branch in the website below - 2 m 18 s to build from scratch after we've also created GitHub release jobs to store intermediate build artifacts. dk can "restore" from one or more GitHub releases and use them as caches: each release has zip files, and dk knows how to use HTTP Range requests to somewhat efficiently get intermediate build artifacts (ex. binary opam packages, the relocatable OCaml compiler). This is the high-performance branch in the website below
Net: If OCaml package maintainers adopted and created these dk-based GitHub releases, then regular OCaml users could access a loose federation of binary caches on their desktops or in CI.
Net Net: I'd love to see if dk can take a stab at lowering the cost curve for AI. Today's AI is very much like opam today: source in + artifacts out, with no sharing of artifacts. But share artifacts and the cost/waste/time/complexity goes down.
AI Provenance: The dk packages (ex. CommonsLang_OCaml) have been 100% AI generated and maintained since June 2026, and "dk" itself was hand built but AI assisted since June 2026.
Caveats: I haven't really tested out macOS and Linux in a long time, but they are in CI. Actually, for my own safety, most of my testing on Windows is in Windows CI to avoid AI badness. And I didn't realize until too late that ocamlearlybird wasn't available for OCaml 5.5 (the first conventional relocatable version), so I have mostly tested with relocatable-patched OCaml 4.14. And I haven't yet separated MSVC packages from MinGW on Windows; you may need Visual Studio on Windows. Expect bugs!
Thanks: @dra27 for spending years getting relocatable OCaml working!
Apology in advance: I think this has some overlap with dune pkg. But I'm on Windows and haven't tried it out.
Links:
- https://jonahbeckford.github.io/ocamlearlybird/ (mini website with performance measurements, how to adopt)
- https://diskuv.com/dk/ (the fine details of the build system; not required for this discuss post)
Running OCaml files straight from VS Code
Tim ats announced
Hi everyone, I'm very glad to introduce a new feature in VSCode OCaml Platform in the release 2.4.0. This work was implemented by Tarides and funded by the OCaml Software Foundation.
A "Run" button has been added to the editor bench. Clicking it opens a dropdown listing executables discovered in your current workspace. This feature was originally targeted at university professors and students, but it can be useful for everyone to quickly debug.
The way executables are discovered depends on the workspace setup. If the user uses Dune and has a dune-project file at the root of the workspace, we take advantage of Dune API to retrieve the list of defined executables and to launch the chosen executable via a basic dune exec ./file. Otherwise, if Dune is not detected as the project builder, the displayed list contains all .ml files discovered in the current workspace, and they are executed with the OCaml bytecode interpreter.
Each time an executable is run, its output is displayed in a dedicated VS Code terminal.
Feedback and bug reports are very welcome!
melange-json is now jsonkit
Pedro Braga announced
Hey there!
A while ago, we moved ppx_deriving_jsonschema into the melange-json project, so one PPX now provides both json decoding/encoding and jsonschema tools. At that point, melange-json no longer described it well, so we renamed melange-json to jsonkit as a project that provides OCaml json tooling. It works exactly like melange-json used to, but you can also handle jsonschema with the same ppx:
open Jsonkit.Primitives
type user = { name : string; age : int } [@@deriving json, jsonschema]
let schema = Jsonkit.Jsonschema.make user_jsonschema
New package names:
| before | after |
|---|---|
melange-json / melange-json.ppx |
jsonkit-melange / jsonkit-melange.ppx |
melange-json-native / melange-json-native.ppx |
jsonkit / jsonkit.ppx |
See the changelog for what changed since the migration.
Old CWN
If you happen to miss a CWN, you can send me a message and I'll mail it to you, or go take a look at the archive or the RSS feed of the archives.
If you also wish to receive it every week by mail, you may subscribe to the caml-list.