Hello Here is the latest OCaml Weekly News, for the week of June 30 to July 07, 2026. Table of Contents ───────────────── opam-minver 0.2.0 - automatically determine minimum dependency versions Zanuda – OCaml linter experiment rpgm-decrypt — a formally-verified RPG Maker asset decryptor in OCaml menhirformat 0.1.0 Solo5 0.12.0 Landmarks 1.7 Why Ocsigen is staying on Lwt (for now) Dune 3.24 Old CWN opam-minver 0.2.0 - automatically determine minimum dependency versions ═══════════════════════════════════════════════════════════════════════ Archive: onetimerobot announced ────────────────────── I have published opam-minver 0.2.0 (previous versions were not released to the public). What it does is use a binary search to find the minimum passing versions of a project's dependencies listed in its opam file and optionally writes them out to the opam file in-place. I wrote this because I was working on another project (not yet published) and got to the point of listing all the dependencies, and realizing I had no idea what versions it was compatible with. This tool finds that out automatically. It's pretty well polished at this point, and it has a cmdliner interface, stores its state in a json file so sessions can be resumed if need be, and it also finds the minimum compiler versions and handles split OCaml compiler bounds if, for example, a project doesn't work specifically with early OCaml 5 versions. This could be used not only for new projects, but also to relax version bounds on any project where they haven't been determined precisely. Homepage and readme is here: Zanuda – OCaml linter experiment ════════════════════════════════ Archive: Continuing this thread, Kakadu announced ──────────────────────────────────────── Zanuda 2.1.0 is merged into opam-repository • OCaml 5.5 support • Lints could be disabled via `[@@@zanuda "-name"]' • Lints represented as ocamlfind packages could be loaded at runtime and defined outside zanuda codebase. This modularity for now is experimental. rpgm-decrypt — a formally-verified RPG Maker asset decryptor in OCaml ═════════════════════════════════════════════════════════════════════ Archive: LulLaS announced ──────────────── Hi everyone))) :slightly_smiling_face: I'd like to share *rpgm-decrypt*, a small command-line tool that decrypts and extracts RPG Maker asset archives (XP / VX / VX Ace via `.rgssad' / `.rgss2a' / `.rgss3a', and MV / MZ via the XOR-encrypted assets and `.pak' archives). It started as a clean-room reimplementation and ended up as an excuse to push OCaml's correctness tooling as far as I could on a real project: • *Gospel* specifications on the pure core (`(*@ ... *)' in the ~.mli~s) • *Why3 + Z3* deductive proofs of the key derivation, little-endian reads and a Zip-Slip path-safety invariant (23/23 goals discharged) • *QCheck* property tests (round-trip / invariants) alongside the unit suite • Coverage-guided *afl-fuzz* of the parsers in CI (0 crashes) • *bisect_ppx* coverage + a small directed mutation-testing pass • Ships as a single static binary via `dune --profile static'; the only external dep is `camlzip' (zlib) for the MZ `.pak' path Build/test runs on the native Windows OCaml switch as well as Linux. Licensed Apache-2.0. Example run: ┌──── │ $ rpgm-decrypt "MyGame" out │ scanned=1817 decrypted=1685 passthrough=132 skipped=0 failed=0 formats=[MV=1817] └──── Repo, docs and prebuilt Windows/Linux binaries: Feedback on the spec/proof setup especially welcome — it's my first serious go at Gospel + Why3, so I'd love to hear how others structure that on real code. menhirformat 0.1.0 ══════════════════ Archive: Federico announced ────────────────── Hello, I'm glad to announce the first release of `menhirformat', a command line tool that formats and indents Menhir and ocamllex source code. It uses the [ocamlformat RPC] to pretty-print the OCaml sections of your lexers and parsers; it also tries its best to preserve the original location of your comments (still needs work in regard to this though!). This is a satellite project of my ongoing and considerably larger effort to add LSP support to these two OCaml dialects, [`menhir-lsp']. The formatting functionality was originally embedded into the LSP server to handle document formatting requests, and I split it out as a standalone application after [this issue]. You can try it out with `opam install menhirformat'. The CLI is highly inspired by ocamlformat's and takes the file to format as argument, e.g. `menhirformat calc.mly'. It exposes a small configuration by which your can tweak the formatter's behavior; read on the available options with `menhirformat --help'. You may also integrate it in your dune project by setting up [dialects] for Menhir and ocamllex: ┌──── │ (dialect │ (name menhir) │ (implementation │ (extension mly) │ (format │ (run menhirformat %{input-file})))) │ │ (dialect │ (name ocamllex) │ (implementation │ (extension mll) │ (format │ (run menhirformat %{input-file})))) └──── Then running `dune build @fmt' will format your project's .mll and .mly files and display a diff. As someone who can't live without format-on-save in their IDE, I was really missing a formatter for Menhir and ocamllex files in the OCaml ecosystem. I hope `menhirformat' fills that void. I'm interested in opinions about the quality of the output and also in suggestions for other customization points of the configuration. Please share below or through a GitHub issue! • opam page: • Source code: Enjoy! [ocamlformat RPC] [`menhir-lsp'] [this issue] [dialects] Solo5 0.12.0 ════════════ Archive: Hannes Mehnert announced ──────────────────────── We are delighted to announce the release of [Solo5 0.12.0]. This has two distinct features: a new hvt [backend for DragonFlyBSD nvmm], thanks to first-time contributor Michael Neumann, and [soft power-off of virtio unikernels] - a [long-standing feature request], which makes using solo5 e.g. on Google compute much smoother – this was initially requested by Michael Bacarella, including draft implementations, and [now implemented] and merged by Romain Calascibetta. Other noteworthy fixes include that `configure.sh' [now checks for the C compiler version] to be at least GCC in version 9 or clang in version 10. The `solo5-hvt-debug' crashed since too strict seccomp rules were applied (since solo5 0.11.0) - thanks to Felix Solcher for opening the [issue], and again Romain Calascibetta for the [fix]. Awaiting opam-repository merge at [Solo5 0.12.0] [backend for DragonFlyBSD nvmm] [soft power-off of virtio unikernels] [long-standing feature request] [now implemented] [now checks for the C compiler version] [issue] [fix] Landmarks 1.7 ═════════════ Archive: Nicolas Ojeda Bar announced ─────────────────────────── Dear community, We are pleased to announce a new release of /Landmarks/, a simple runtime profiler for OCaml. The main novelty in this release is the possibility of defining custom backends to generate reports that can be consumed by external viewers. An example backend that produces reports is included in a new library `landmarks-speedscope'. Custom backends can be defined in external libraries without needing to modify `landmarks' itself. This support was added by @mjambon. Happy profiling! Cheers, Nicolas Why Ocsigen is staying on Lwt (for now) ═══════════════════════════════════════ Archive: Vincent Balat announced ─────────────────────── Over 2025 we migrated the whole Ocsigen stack (ocsigenserver, Eliom, ocsigen-toolkit, ocsigen-start) from Lwt to Eio. The migration compiles and the test suite passes. We have nonetheless decided **not to release it and to stay on Lwt for now**, and we wrote up why. Two obstacles stopped us: • *Loss of function coloring.* Under Lwt, a `_ Lwt.t' in a type tells you a call may suspend or do I/O. In a multi-tier framework like Eliom this is crucial: the *same* shared expression can be a local call on the server and a network round-trip on the client. Without coloring, nothing at the call site tells you where to put a spinner, and reactive combinators (`React' / `map_s') silently lose the guarantee that they are pure. • *Eio's handler model vs browser events.* On the client, DOM event handlers are called directly by the browser with no Eio handler on the stack, so any `perform' crashes. The usual workaround (`Eio_js.start') defers the body via `setTimeout(0)', which runs after event propagation and breaks `preventDefault' / `stopPropagation'. This is *not* an anti-Eio post. Effects are a major achievement of OCaml 5 and we are grateful to the multicore team. We also think the monadic style is genuinely fine (with `let*' it is comfortable to write), and `Lwt_direct' is there for those who dislike monads. Our broader worry is ecosystem unity: very large Lwt codebases exist, underfunded projects cannot afford such a migration, and a split would hurt a community that is already small. To help, we released [`ciao-lwt'] (Lwt-to-Eio migration tools), funded by NLnet through NGI Zero Core and Tarides. We would love the effects community's view on directions that could unblock us, including improving Lwt itself (io_uring, effects, multicore). Full write-up: Feedback, ideas and constructive disagreement very welcome. [`ciao-lwt'] Dune 3.24 ═════════ Archive: Shon announced ────────────── The Dune team is pleased to announce [the release of dune 3.24.0]. Highlights include the following • Dune package management now uses the relocatable compiler by default, for all supported compiler versions. This brings a massive speedup to workspace setup in the many cases where built compiler versions can be reused. ([ocaml/dune#14357], [@Alizter]) • Directory targets are now generally available ([ocaml/dune#14579]), allowing tools to produce entire directory trees as targets. See the [documentation on directory targets] for details. • Path handling has been refined, improving the consistency of paths across platforms ([ocaml/dune#14278] and [ocaml/dune#14278]) and using a more consistent and disciplined location for `%{bin:NAME}' variable expansions ([ocaml/dune#14432]). • Path-valued percent forms (`%{bin:...}', `%{dep:...}', `%{path:...}', and friends) now expand same-directory paths with a leading `./', so that shells like `bash' in `(bash ...)' and `(system ...)' actions execute them directly instead of looking them up in `PATH' ([ocaml/dune#15156]). This is a breaking change for configurations that were handling paths naively, and neglected to normalize the representation before using it test fixtures or for constructing other strings. • The deprecated `lang coq' has been removed, as scheduled, superseded by `lang rocq'. See [ocaml/dune#12788] for details. See [the full changelog] for all new features and fixes, and for attribution to the contributors who made it all possible. Thank you, contributors! If you encounter a problem with this release, please report it in [our issue tracker]. [the release of dune 3.24.0] [ocaml/dune#14357] [@Alizter] [ocaml/dune#14579] [documentation on directory targets] [ocaml/dune#14278] [ocaml/dune#14432] [ocaml/dune#15156] [ocaml/dune#12788] [the full changelog] [our issue tracker] 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]. [Alan Schmitt] [send me a message] [the archive] [RSS feed of the archives] [caml-list] [Alan Schmitt]