Hello Here is the latest OCaml Weekly News, for the week of February 24 to March 03, 2026. Table of Contents ───────────────── Lwt.6.1.0, Lwt_ppx.6.1.0 OCaml Platform Newsletter: November 2025 to January 2026 Announcing the first release of Alice, a radical OCaml build system mnet, a new TCP/IP stack for unikernels in OCaml Experiment: format-line Caml in the Capital - Registrations Open! Experimental tools for migrating from Lwt to Eio First alpha release of OCaml 5.5.0 NotInriaCaml_Std.Wenv@0.1.0 - create Windows envs on macOS [dk0] Running Real Docker Containers in OCaml Tests I wrote a DSL for AI personalities in OCaml Outreachy May 2026 Old CWN Lwt.6.1.0, Lwt_ppx.6.1.0 ════════════════════════ Archive: Continuing this thread, Raphaël Proust announced ──────────────────────────────────────────────── Lwt.6.1.1 has been released. It contains a fix to support build with OCaml.5.5. Thanks to @kit-ty-kate for the contribution. OCaml Platform Newsletter: November 2025 to January 2026 ════════════════════════════════════════════════════════ Archive: Sabine Schmaltz announced ───────────────────────── Welcome to the seventeenth edition of the OCaml Platform newsletter! In this November 2025 to January 2026 edition, we are excited to bring you the latest on the OCaml Platform, continuing our tradition of highlighting recent developments as seen in [previous editions]. To understand the direction we're headed, especially regarding development workflows and user experience improvements, check out our [roadmap]. You can [subscribe to this newsletter on LinkedIn]! *Highlights:* • *opam 2.5.0 Released*: Major release featuring incremental opam file loading for up to 70% faster `opam update', improved shell integration, and better macOS sandbox support • *Relocatable OCaml Merged*: The final piece of the relocatable OCaml puzzle was merged in December, enabling opam to clone switches instead of recompiling them. This will be available in the first alpha release of OCaml 5.5 • *Dune 3.21.0*: Large release with dozens of fixes, improvements, and new features including OxCaml compiler support and copy-on-write file operations • *Enhanced Editor Support*: OCaml-LSP 1.25.0 adds `.mlx' file support with formatting, diagnostics, and code actions, plus new custom requests • *Merlin 5.6.1-504*: Performance optimizations, smarter signature help, and fixed completion for inlined record labels • *opam-publish 2.7.1*: Fixes for GitHub API token permissions • *dune-release 2.2.0*: Full compatibility with cmdliner 2.0.0 • *opam-repository Archival*: January 1, 2026 archival run removed 3,264 package versions to maintain repository sustainability *Backstage OCaml:* • [OCaml Infrastructure: How the opam-repository Works] (Nov 5, 2025) *Stable Releases:* • [opam-publish 2.7.1] (Nov 18, 2025) • [opam 2.5.0] (Nov 27, 2025) • [Merlin 5.6.1-504] (Dec 20, 2025) • [OCaml-LSP 1.25.0] (Dec 20, 2025) • [Dune 3.21.0] (Jan 16, 2026) • [dune-release 2.2.0] (Jan 29, 2026) *Unstable Releases:* • [opam 2.5.0~rc1] (Nov 20, 2025) • [opam 2.5.0~beta1] (Nov 10, 2025) [previous editions] [roadmap] [subscribe to this newsletter on LinkedIn] [OCaml Infrastructure: How the opam-repository Works] [opam-publish 2.7.1] [opam 2.5.0] [Merlin 5.6.1-504] [OCaml-LSP 1.25.0] [Dune 3.21.0] [dune-release 2.2.0] [opam 2.5.0~rc1] [opam 2.5.0~beta1] OCaml Compiler ╌╌╌╌╌╌╌╌╌╌╌╌╌╌ ◊ Relocatable OCaml Merged In December 2025, the final piece of the [Relocatable OCaml] puzzle was merged, enabling opam to clone switches instead of recompiling them. This feature will be available in the first alpha release of OCaml 5.5. *What Relocatable OCaml Enables:* This feature allows the OCaml compiler and its associated tools to be moved to different filesystem locations after installation without breaking functionality. Key benefits include: • Binary distributions that work regardless of installation path • Improved flexibility for package managers organizing OCaml installations • Bundling of specific OCaml versions by developer tools without path conflicts • Simplified cross-platform distribution The implementation is the culmination of work by David Allsopp, with review from Samuel Hym, Jonah Beckford, and others. See the [announcement on Discuss] and the [merged PRs] ([#14244], [#14245], [#14246], [#14247]) for technical details. [Relocatable OCaml] [announcement on Discuss] [merged PRs] [#14244] [#14245] [#14246] [#14247] Build System ╌╌╌╌╌╌╌╌╌╌╌╌ ◊ Dune [Dune 3.21.0] (January 16, 2026) is a large release including dozens of fixes, improvements, and additions from many contributors. *Notable Additions:* • (Experimental): `library_parameter' stanza for the OxCaml compiler • Copy-on-write (COW) when copying files on supporting filesystems (Btrfs, ZFS, XFS) under Linux • Support for Tangled ATproto-based code repositories • New `(dir ..)' field on packages to filter stanzas with `--only-packages' • `dune promotion show' command to preview corrected files • New `(lang rocq)' build mode for Rocq 9.0 and later • Support for instantiating OxCaml parameterised libraries • `dune describe tests' to list tests in the workspace • Horizontal scrolling in TUI • Support for expanding variables in `(promote (into ..))' *Notable Fixes:* • Fixed `include_subdirs qualified' picking the furthest module instead of the closest • Improved error messages for invalid version formats with non-ASCII characters • Fixed crash when running `dune build @check' on libraries with virtual modules • Allow `$ dune init' to work on absolute paths • Stop hiding the `root_module' from the include path For the complete list of changes, see the [full release on GitHub]. *Dune Maintained by*: Rudi Grinberg (@rgrinberg, Jane Street), Nicolás Ojeda Bär (@nojb, LexiFi), Marek Kubica (@Leonidas-from-XIV, Tarides), Ali Caglayan (@Alizter, Tarides), Stephen Sherratt (@gridbugs, Tarides), Antonio Nuno Monteiro (@anmonteiro), Sudha Parimala (@Sudha247, Tarides), Ambre Suhamy (@ElectreAAS, Tarides), Puneeth Chaganti (@punchagan, Tarides) [Dune 3.21.0] [full release on GitHub] Package Management ╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌ ◊ opam [opam 2.5.0] (November 27, 2025) is a major release with significant performance and usability improvements. *Key Features:* • *Massive speedup for `opam update'*: Thanks to @arozovyk, opam update now loads opam files incrementally, only parsing files that have changed since the last update. For typical small diffs, this means operations that took seconds now complete in milliseconds • *Improved shell integration*: Fixed issues where parts of a previous environment were kept in the current environment, causing various problems • *Changed default shell integration file*: Now writes to `.bashrc' instead of `.profile' when bash is detected, preventing infinite loop issues • *AppArmor profile*: The install script now installs an appropriate apparmor profile on systems configured with apparmor (enabled by default on Ubuntu) • *macOS sandbox improvements*: Allow writing to `/var/folders/' and `/var/db/mds/' directories as required by some macOS core tools *Build Changes:* • *Ecosystem cmdliner 2.0.0 compatibility*: opam no longer depends on `cmdliner', removing a key blocker that prevented cmdliner 1.x and 2.0.0 from being co-installable. This change enables ecosystem-wide migration to cmdliner 2.0.0 • OCaml 5.5 (trunk) support when using dune's dev profile • The release archive (`opam-full-*.tar.gz') is now reproducible • OpenBSD binary is now a full static binary For more details, see the [official opam 2.5.0 announcement blog] and [full release notes on GitHub]. *opam Maintained by*: Raja Boujbel (@rjbou, OCamlPro), Kate Deplaix (@kit-ty-kate, Ahrefs), David Allsopp (@dra27, Tarides) [opam 2.5.0] [official opam 2.5.0 announcement blog] [full release notes on GitHub] ◊ opam-publish [opam-publish 2.7.1] (November 18, 2025) fixes bugs related to the GitHub API token permissions introduced in version 2.7.0. *Changes:* • Advertise the need, and check, for the `workflow' scope for GitHub personal access tokens • Enforce the git remote used to push branches to users' fork to be used instead of the SSH method • Avoid potential previously used tokens with wrong permissions to be used instead of the new one • Add support for the opam 2.5 API *Maintained by*: Raja Boujbel (@rjbou, OCamlPro), Kate Deplaix (@kit-ty-kate, Ahrefs) [opam-publish 2.7.1] ◊ opam-repository Archival: January 1, 2026 On January 1, 2026, the opam-repository completed its scheduled archival run, removing *3,264 package versions* (881 unique packages) marked with `x-maintenance-intent: archival'. This ongoing maintenance process helps keep the repository manageable by removing unmaintained or obsolete package versions. *What This Means:* • Archived packages are no longer available in the default opam repository • CI systems and lock files may need updates if they depend on archived versions • The archival is based on metadata explicitly set by package maintainers *Background:* The archival process was announced by Hannes Mehnert in December 2025 (see the [Discuss announcement]), giving package maintainers and users time to prepare. Packages can be restored from archival by maintainers upon request. This maintenance practice ensures the opam repository remains sustainable and focused on actively maintained packages. [Discuss announcement] ◊ dune-release [dune-release 2.2.0] (January 29, 2026) brings full compatibility with cmdliner 2.0.0, continuing the ecosystem-wide migration that began with opam 2.5.0's removal of the cmdliner dependency. *Why This Matters:* cmdliner 2.0.0 introduced stricter requirements that improve CLI reliability but prevent co-installability with cmdliner 1.x. Following opam 2.5.0's lead in removing this conflict, dune-release 2.2.0 updates to use cmdliner 2.0.0 exclusively. This coordinated effort across the platform tools enables users to upgrade without encountering dependency conflicts. *Important Changes:* • *Breaking*: Following cmdliner 2.0's stricter requirements, prefix-matching for command options is no longer supported • Users must now provide the full wording for all flags (for example, `--skip-tests' instead of `--skip-test') • This change ensures compatibility with cmdliner 2.0.0 and aligns with modern CLI best practices • If you have automation scripts using shortened flags, update them before upgrading For technical details, see the [cmdliner 2.0.0 documentation] and the [dune-release PR #512]. *Maintained by*: Tarides [dune-release 2.2.0] [cmdliner 2.0.0 documentation] [dune-release PR #512] Editor Tools ╌╌╌╌╌╌╌╌╌╌╌╌ *Roadmap: [Edit / (W19) Navigate Code]* [Edit / (W19) Navigate Code] ◊ OCaml-LSP Server [OCaml-LSP 1.25.0] (December 20, 2025) introduces support for `.mlx' files and new custom requests. *Features:* • *`.mlx' Support*: Added support for `.mlx' files, including diagnostics, code actions, hover, and formatting via `ocamlformat-mlx' • *New Custom Requests*: Added `typeExpression', `locate', and `phrase' requests to the server • *Code-Lens Configuration*: Code-lens for nested `let' bindings is now configurable *Fixes:* • The server now falls back to `.merlin' configuration if a `dune-project' file is missing, provided [dot-merlin-reader] is installed • Improved precision of timestamps for collected metrics [OCaml-LSP 1.25.0] [dot-merlin-reader] ◊ Merlin [Merlin 5.6.1-504] (December 20, 2025) brings performance optimizations and improved stability. *Key Improvements:* • *Smarter Signature Help*: Now triggers correctly on unfinished `let ... in' bindings and no longer appears redundantly on function names • *More Reliable Completion*: Fixed issues with completion for inlined record labels • *Improved Performance*: Optimized buffer indexing and path calculations • *Bug Fixes*: Resolved a bug where the `document' command concatenated labels and variants incorrectly *OCaml LSP Server maintained by*: Ulysse Gérard (@voodoos, Tarides), Xavier Van de Woestyne (@xvw, Tarides), Rudi Grinberg (@rgrinberg, Jane Street) *Merlin maintained by*: Ulysse Gérard (@voodoos, Tarides), Xavier Van de Woestyne (@xvw, Tarides), Muluh Godson (@PizieDust, Tarides) [Merlin 5.6.1-504] ◊ OCaml-eglot We have drastically modified the `xref' backend (allowing navigation from definition to definition) to make it more suitable for OCaml. In addition, we added the ability to annotate the type of an enclosing active_ (used with the `ocaml-eglot-type-enclosing' command) or simply to type the selection. These updates have been merged into `main', making them available via a MELPA update. *ocaml-eglot maintained by*: Xavier Van de Woestyne (@xvw, Tarides) Platform Infrastructure ╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌ ◊ OCaml Infrastructure: How the opam-repository Works The [November 5, 2025 article on the opam-repository] provides an in-depth look at this critical piece of OCaml infrastructure. The opam repository serves as the central package registry for the OCaml ecosystem, hosting over 4,500 packages. It relies on dedicated volunteer maintainers who review every submission. — As always, we encourage feedback and contributions from the community as we continue to improve the OCaml Platform ecosystem. [November 5, 2025 article on the opam-repository] Announcing the first release of Alice, a radical OCaml build system ═══════════════════════════════════════════════════════════════════ Archive: Continuing this thread, Steve Sherratt announced ──────────────────────────────────────────────── Announcing the release of [Alice v0.5.0] which introduces parallel builds. [Alice v0.5.0] mnet, a new TCP/IP stack for unikernels in OCaml ════════════════════════════════════════════════ Archive: Calascibetta Romain announced ───────────────────────────── I am pleased to announce a series of releases for developing unikernels with OCaml 5 and [Miou]. After extensive testing, we are now able to offer a new TCP/IPv4 and IPv6 stack in OCaml that aims to replace [mirage-tcpip] and pave the way for direct-style unikernel development. Below is an overview of the libraries we have built to make this possible. [Miou] [mirage-tcpip] mkernel ╌╌╌╌╌╌╌ `mkernel' is a small library that provides the essentials for developing a unikernel targeting [Solo5] or [Unikraft]. Its purpose is to expose hypercalls (the unikernel equivalent of syscalls) so that your application can interact with network and block devices. We recommend reading the `mkernel' [documentation] to understand the key concepts behind unikernels (hypercalls, devices, tenders, etc.). The [slides] we presented at the last [MirageOS retreat] are also helpful for understanding our new workflow. Compiling a unikernel now only requires `dune' and vendored libraries. We have therefore chosen not to resolve dependencies automatically (as [opam-monorepo] did) or to impose them (as the `mirage' tool does), giving developers full freedom to build their unikernels as they see fit. In particular, this makes it straightforward to use ppx rewriters, which was difficult or impossible with the `mirage' tool. [Solo5] [Unikraft] [documentation] [slides] [MirageOS retreat] [opam-monorepo] ◊ A new workflow and targets This release is experimental: Xen is not yet supported, and Unikraft support is partial. However, both platforms are on our roadmap, so if you are interested in them, please let us know! We are also developing tooling to streamline the workflow, with the guiding principle that these tools should never dictate which dependencies your unikernel uses or which build system you choose. mnet ╌╌╌╌ `mnet' is the centerpiece of this release. It is designed to replace (and improve upon) [mirage-tcpip] by offering a direct-style API built on effects. The API deliberately mirrors the `Unix' socket interface: `connect', `listen', `accept', `read', `write', and `close' all behave the way you would expect. Here is a small example of an echo server: ┌──── │ let run (ipv4, gateway, ipv6) = │ Mkernel.(run [ rng; Mnet.stack ~name:"service" ?gateway ~ipv6 ipv4 ]) │ @@ fun rng (daemon, tcp, udp) -> │ let@ () = fun () -> Mnet.kill daemon in │ let@ () = fun () -> Mirage_crypto_rng_mkernel.kill rng in │ let listen = Mnet.TCP.listen tcp 9000 in │ let flow = Mnet.TCP.accept tcp listen in │ let buf = Bytes.create 4096 in │ let rec echo () = │ let len = Mnet.TCP.read flow buf in │ if len > 0 then begin │ Mnet.TCP.write flow (Bytes.sub_string buf 0 len); │ echo () │ end │ in │ let@ () = fun () -> Mnet.TCP.close flow in │ echo () └──── TLS support (via [ocaml-tls]) is already available, allowing you to establish secure connections with your unikernel. DNS resolution (via [ocaml-dns]) and the [Happy Eyeballs] algorithm are also included, so that a unikernel can resolve hostnames and connect to remote services over both IPv4 and IPv6. A [short tutorial] walks you through creating an echo server as a unikernel, similar to what we [already offer] for Miou. For the curious, an article about IPv4 and Miou is available [here]. Beyond the move to effects for all scheduling, I would like to give special thanks to: • Edwin Török for proposing fixes to prevent denial-of-service attacks, which have been integrated into `mnet' (in particular for [ARP]). • Nicolas Ojeda Bär for contributing an IPv6 implementation that we adopted and improved (caches, packet fragmentation and reassembly, etc.) • Reynir for patiently debugging PCAP traces • Hannes for sharing his deep knowledge of the TCP protocol and its interactions with IPv4 and IPv6 As well as others who participated in the development of `mnet' in one way or another. [mirage-tcpip] [ocaml-tls] [ocaml-dns] [Happy Eyeballs] [short tutorial] [already offer] [here] [ARP] ◊ Developing and deploying unikernels This library also marks a turning point in our approach to unikernels. We no longer treat a regular OCaml application as something that can be transparently turned into a unikernel. Developing a unikernel now means developing a unikernel from the start. In our experience, trying to retrofit an existing application into a unikernel was neither practical nor worthwhile. Our tutorial therefore covers both the development and deployment of unikernels. On the deployment side, we also recommend exploring [Albatross]. [Albatross] utcp ╌╌╌╌ [`utcp'] is a pure OCaml implementation of the TCP protocol, used internally by `mnet' to handle TCP connections. The implementation is based on a state machine and performs no I/O itself, making it easy to test and reason about. `utcp' covers the full TCP lifecycle: the three-way handshake, reliable in-order data delivery with retransmissions, flow control, congestion control, and connection teardown. It has been tested extensively through our end-to-end unikernel tests (a simple [echo] server and client, and a [DNS resolver]). [`utcp'] [echo] [DNS resolver] ◊ Unikernels and proofs `utcp' also reflects our ambition to incorporate, as time permits, proof-based implementations. Other examples include: • miou with its priority queue (see the [VOCAL] project) • mirage-crypto with certain cryptographic primitives (see the [fiat] project) • and now utcp (see [netsem]) This effort is still in its early stages, but we welcome improvements and collaborations in this area. [VOCAL] [fiat] [netsem] mhttp ╌╌╌╌╌ To reach a wider audience, we also provide an HTTP protocol implementation for unikernels, building on the work we started (and currently use in production) with [httpcats]. `mhttp' is essentially a unikernel-oriented counterpart to `httpcats', using [ocaml-h1] and [ocaml-h2] as its HTTP/1.1 and H2 backends. [httpcats] [ocaml-h1] [ocaml-h2] ◊ Ecosystem and composability Although `mhttp' is a small project, it illustrates a broader principle behind our cooperative's approach to library development. As we have [stated before], everything we build is designed to be reusable with schedulers other than Miou and in contexts other than unikernels. Regardless of which scheduler one prefers, we believe in a pragmatic, cooperative approach to contributing to the community. Our primary focus remains unikernel development, but years of experience building protocol and format libraries have taught us that keeping them scheduler-agnostic is in everyone's best interest, for maintainability, testability, and reliability alike. Wherever possible, you will find a general-purpose library alongside its unikernel counterpart: `httpcats' and `mhttp' are one such pair. [stated before] Vifu ╌╌╌╌ As [previously announced], we have developed a web framework for OCaml 5 called [vif], which we use in production for our [builds.robur.coop] website (we recommend the [tutorial] presented at [FUN OCaml] 2025). `vif' now has a unikernel variant: `vifu'. It offers nearly the same interface as `vif' (except for static file management), making it possible to build websites entirely in OCaml. Here is a small unikernel that displays "Hello World!": ┌──── │ let hello_world req _server () = │ let open Vifu.Response.Syntax in │ let* () = Vifu.Response.with_text req "Hello World!\n" in │ Vifu.Response.respond `OK │ │ let run (ipv4, gateway, ipv6) = │ Mkernel.(run [ rng; Mnet.stack ~name:"service" ?gateway ~ipv6 ipv4 ]) │ @@ fun rng (daemon, tcp, udp) -> │ let@ () = fun () -> Mnet.kill daemon in │ let@ () = fun () -> Mirage_crypto_rng_mkernel.kill rng in │ let cfg = Vifu.Config.v 80 in │ let routes = Vifu.[ get (rel /?? any) --> hello_world ] in │ Vifu.run ~cfg tcp routes () └──── *disclaimer*: If you would like to use `vifu', please note that although a recent release has been made, one final fix is still needed to compile a unikernel with this library (to avoid pulling in the `unix' module). We recommend pinning `vifu' for now. [previously announced] [vif] [builds.robur.coop] [tutorial] [FUN OCaml] Unikernels ╌╌╌╌╌╌╌╌╌╌ Behind all these libraries, there are concrete projects that we would like to share with you: • Our [`immutable'] unikernel, a web server for static files (which can be generated, for example, with [YOCaml]). • A DNS resolver unikernel: [`pagejaune'] • A small search engine for emails from an archive such as the caml-list: [`blame']. More details are available [here]. [`immutable'] [YOCaml] [`pagejaune'] [`blame'] [here] Conclusion ╌╌╌╌╌╌╌╌╌╌ After several years of work, we are now able to develop unikernels with OCaml 5 in earnest. We hope that our new workflow will be of interest to the community and that these libraries will be a useful contribution to the OCaml ecosystem. If you would like to try it out, we recommend starting with the [mnet tutorial] and the [mkernel documentation]. Feel free to open issues or reach out to us if you have any questions! [mnet tutorial] [mkernel documentation] Experiment: format-line ═══════════════════════ Archive: Emile Trotignon announced ───────────────────────── I made this little experiment a while back: The idea is to provide a complement to ocp-indent to decide which token should be separated by whitespace and which should not. For now it is based only on lexing information, which make the code simple but also does not always provide enough information to have a nice formatting. An idea of the output can be read here: The project itself is formatted with ocamlformat, and in the there is a diff of what this changes compared to ocamlformat, on the main source file. I think this approach could be improved by having a hybrid ast-token stream datastructure. Something where you work on a stream of token but you can query the AST context of a given token. What do you think ? Caml in the Capital - Registrations Open! ═════════════════════════════════════════ Archive: Continuing this thread, Sacha Ayoun announced ───────────────────────────────────────────── And here is the [link to the recording]! We'd like to thank our speakers Jeremy and Nick again, as well as the ~30 attendees to the meetup! It was great having you, and we hope to see you again next time :) [link to the recording] Experimental tools for migrating from Lwt to Eio ════════════════════════════════════════════════ Archive: Jules announced ─────────────── We developed tools to help us migrate Ocsigen libraries and applications to direct-style concurrency and we are happy to share them. There are 4 independent tools for different purposes: • Replacing every uses of `lwt_ppx' with `Lwt' function calls (e.g. replacing `let%lwt ... in' with `let* ... in'). This is purely syntactic and allows you to easily remove a PPX. It handles inserting `open Lwt.Syntax' at the top of the file. • Warning about occurrences of `let _ = ...' and `ignore ...', which make the next tools less reliable. These are called “implicit fork” because code run concurrently if the ignored value is an Lwt thread. This requires an explicit call to `Fiber.fork' with Eio. • Migrating uses of `Lwt_log' to `Logs'. It was used on [ocsigenserver] for example. At this point we generate code working as before and did not introduce a dependency on Eio. • Migrating uses of `Lwt' to `Eio'. It rewrites code written in monadic style into direct-style, for example this code: ┌──── │ let _ = │ let* x = f 1 in │ let+ y = f 2 in │ Lwt.bind (f 3) (fun z -> │ Lwt.return (x + y + z)) └──── is rewritten to: ┌──── │ let _ = │ let x = f 1 in │ let y = f 2 in │ let z = f 3 in │ x + y + z └──── It also rewrite `Lwt' function calls to their equivalent in `Eio' and handles many IO operations. Unfortunately, this tool doesn’t generate fully equivalent code and requires manual modifications. Comments are inserted in many places where intervention is needed. An example of generated incorrect code is: ┌──── │ let _ = │ let a = operation_1 () in │ let* b = operation_2 () in │ let* a = a in │ Lwt.return (a + b) └──── which is rewritten into: ┌──── │ let _ = │ let a = operation_1 () in │ let b = operation_2 () in │ let a = a in │ a + b └──── This is incorrect because `operation_1' and `operation_2' are now sequential but were concurrent before. This is a case of an implicit fork that cannot easily be detected. The correct transformation would be: ┌──── │ let _ = │ let a, b = Eio.Fiber.pair operation_1 operation_2 in │ a + b └──── We could achieve the migration on [eliom] and [ocsigenserver] All the tools use OCamlformat under the hood to generate the code. This has the inconvenient of enforcing the use of OCamlformat before using them as they will reformat the entire codebase. The last two tools use Merlin under the hood to locate uses of `Lwt' functions in the source files. This works by reading Merlin’s ocaml-index files built by Dune to extract the location in the source files that we need. Currently, it only supports Eio as a backend but can easily be [adapted] to other direct-style concurrency libraries. This work was made possible thanks to the support of the [NGI Zero Core fund] through the [Nlnet foundation], and is perfomed by [Tarides]. [ocsigenserver] [eliom] [ocsigenserver] [adapted] [NGI Zero Core fund] [Nlnet foundation] [Tarides] First alpha release of OCaml 5.5.0 ══════════════════════════════════ Archive: octachron announced ─────────────────── Four months after the release of OCaml 5.4.0, the set of new features for the future version 5.5.0 of OCaml has been frozen. We are thus happy to announce the first alpha release for OCaml 5.5.0. This alpha version is here to help fellow hackers join us early in our bug hunting and opam ecosystem fixing fun (see below for the installation instructions). More information about the release process is available at . The progress on stabilising the ecosystem is tracked on the [opam readiness for 5.5.0 meta-issue] . There is also a companion alpha opam repository available for this alpha release ┌──── │ $ opam repo add alpha git+https://github.com/kit-ty-kate/opam-alpha-repository.git └──── which contains in-progress alpha releases of opam packages that are being updated for OCaml 5.5.0 . The full release is expected between May and June. There are more information available in the [prospective release calendar]. If you find any bugs, please report them on the [OCaml's issue tracker]. If you are interested in the ongoing list of new features and bug fixes, the updated [change log for OCaml 5.5.0 is available on GitHub]. Happy hacking, Florian Angeletti for the OCaml team [opam readiness for 5.5.0 meta-issue] [prospective release calendar] [OCaml's issue tracker] [change log for OCaml 5.5.0 is available on GitHub] Installation Instructions ╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌ The base compiler can be installed as an opam switch with the following commands on opam 2.1 and later: opam update opam switch create 5.5.0~alpha1 The source code for the alpha is also available at these addresses: • GitHub: • OCaml archives at Inria: Fine-Tuned Compiler Configuration ╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌ If you want to tweak the configuration of the compiler, you can switch to the option variant with: ┌──── │ opam update │ opam switch create ocaml-variants.5.5.0~alpha1+options └──── where `option_list' is a space separated list of `ocaml-option-*' packages. For instance, for a flambda and no-flat-float-array switch: ┌──── │ opam switch create 5.5.0~alpha1+flambda+nffa ocaml-variants.5.5.0~alpha1+options ocaml-option-flambda ocaml-option-no-flat-float-array └──── All available options can be listed with `opam search ocaml-option'. NotInriaCaml_Std.Wenv@0.1.0 - create Windows envs on macOS [dk0] ════════════════════════════════════════════════════════════════ Archive: jbeckford announced ─────────────────── It is my pleasure to announce the following package for [the dk0 build system] that creates a Windows environment ("wenv") using a custom Wine build for macOS: • [NotInriaCaml_Std.Wenv@0.1.0] Here is a sample session: ┌──── │ # Simplest way to install dk0 today. Use ~git pull~ if exists already. │ $ git clone --branch V2_5 https://github.com/diskuv/dk.git dksrc │ │ # Clear out data, cache and intermediate files from any prior │ # experiments (from the "--trial" option seen in [ANN] posts) │ $ rm -rf t/ │ │ # With the default Lua rules ("-I dksrc/etc/dk/v"), run the │ # OCaml Windows environment creation rule ("run │ # NotInriaCaml_Std.Wenv.Create@0.1.0"). Tell the rule to create the │ # wenv at target/my-wenv/ ("dir=...") and make a mount │ # ("mount[]=...") inside the wenv where the Unix directory $PWD is │ # mapped to Windows M:\project. Depending on Internet, expect 3-4 │ # minutes for a single-threaded download of artifacts (581MB). │ $ dksrc/dk0 --trial -I dksrc/etc/dk/v \ │ run NotInriaCaml_Std.Wenv.Create@0.1.0 \ │ dir=$PWD/target/my-wenv \ │ "mount[]=type=bind,src=$PWD,dst=M:/project" └──── ┌──── │ # Then enter the wenv by running Command Prompt ("cmd.exe"). Turn │ # off Wine debug messages ("WINEDEBUG=-all"). Remember that │ # Ctrl-Z is the Windows equivalent of Ctrl-D (EOF) in Unix. │ $ WINEDEBUG=-all target/my-wenv/bin/enter cmd.exe │ │ Microsoft Windows 10.0.19045 │ Z:\> ocamlopt -config │ Z:\> gcc --version │ Z:\> dir M: │ 02/27/2026 10:24 AM project │ Z:\> ocaml │ OCaml version 5.4.1 │ │ Enter #help;; for help. │ │ # 1+1 ;; │ - : int = 2 │ │ # ^Z │ │ Z:\> echo let () = print_endline "abcxyz" > letters.ml │ Z:\> ocamlopt -o letters.exe letters.ml │ Z:\> .\letters.exe │ abcxyz │ Z:\> exit └──── Details: • MinGW with UCRT Windows API and LLVM toolchain (llvm-mingw) for Wine on the host (macOS). X11 has been disabled. • MinGW with MSVCRT Windows API and GNU compiler and BusyBox binaries (w64devkit) inside Windows guest. • Wine has good support for programs that use Windows conventions (MSVC, Windows API rather than `syscall', etc). But there are important programs that won't work correctly today: MSYS2/Cygwin, Rust uutils. Enjoy! –jonah [the dk0 build system] [NotInriaCaml_Std.Wenv@0.1.0] Running Real Docker Containers in OCaml Tests ═════════════════════════════════════════════ Archive: Sachin announced ──────────────── Hi everyone, I’ve been working on a project called *[testcontainers-ocaml]*, which brings Testcontainers style integration testing to OCaml. The idea is simple: Instead of mocking infrastructure (Postgres, Redis, Kafka, etc.), start real Docker containers inside your test suite and tear them down automatically. — [testcontainers-ocaml] Why? ╌╌╌╌ In many OCaml projects, integration tests either: • Rely on mocks • Depend on globally running services • Or are skipped entirely in CI Mocks are useful, but they don’t catch issues like: • Schema mismatches • Connection pool behavior • Real networking failures • Startup timing problems • Migration issues Spinning up disposable containers per test gives us: • Isolated test environments • No shared global state • CI reproducibility • Real infrastructure behavior Current Status ╌╌╌╌╌╌╌╌╌╌╌╌╌╌ The project is currently incubating under the Docker organization. I’m still actively shaping the API and would really appreciate feedback from the OCaml community on: • API ergonomics • Prebuilt modules (Postgres, Redis, etc.) • Testing best practices in OCaml If anyone here has experience with integration testing patterns in OCaml, I’d love to hear thoughts. Thanks! I wrote a DSL for AI personalities in OCaml ═══════════════════════════════════════════ Archive: Griffin announced ───────────────── Hi guys, I wanted a more deterministic way to create personalities for my AI agents that was consistent in production. The interesting catch being that the compiler had to output a prompt, and it needed to be accessible for agents in Python. The solution was this DSL, a format for writing deterministic categories (similar to YAML) that compile to a prompt injectable into Langchain agents. OCaml was the natural choice due to its performance and proven capabilities to host compilers (Rust obv). Looking for beta testers and any feedback is welcome! Outreachy May 2026 ══════════════════ Archive: Patrick Ferris announced ──────────────────────── Hello everyone, The OCaml community has signed up to Outreachy May 2026 (see [past] [posts])! *What is Outreachy?* Outreachy is a paid, remote internship program. Outreachy promotes diversity in open source and open science. Our internships are for people who face under-representation, and discrimination or systemic bias in the technology industry of their country. The current round is still ongoing with interns making great progress with @tmattio on [Raven], with @xvw on [YOCaml] and with myself on [ocaml-tiff]. [past] [posts] [Raven] [YOCaml] [ocaml-tiff] Important Dates ╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌ For this next round, the important dates are as follows (these are always subject to some change): • Mar 1 - Community sign up deadline :white_check_mark: • Mar 14 - [Mentor Signup] • Mar 17 to Apr 15 - Contribution period • May 18 to Aug 17 - Internship period *Our next deadline is for mentors to sign up to the OCaml community* with a project idea. Please do consider being an Outreachy mentor. If you have any questions or ideas you can always reach out to me directly. If you need a refresher of past projects, there’s a dedicated page on the OCaml website: [OCaml Outreachy Internships]. Feel free to discuss ideas on this thread too! The OCaml community is currently able to financially support Outreachy internships thanks to the generous support of [Tarides] and [Janestreet]. This includes being able to fund mentors as well. Thanks! :camel: [Mentor Signup] [OCaml Outreachy Internships] [Tarides] [Janestreet] 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]