OCaml Weekly News

Previous Week Up Next Week

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

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

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:

Stable Releases:

Unstable Releases:

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.

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)

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-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-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.

  • 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

Editor Tools

  • 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
  • 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)

  • 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.

Announcing the first release of Alice, a radical OCaml build system

Continuing this thread, Steve Sherratt announced

Announcing the release of Alice v0.5.0 which introduces parallel builds.

mnet, a new TCP/IP stack for unikernels in OCaml

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.

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.

  • 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.

  • 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.

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).

  • 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.

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.

  • 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.

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.

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.

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!

Experiment: format-line

Emile Trotignon announced

I made this little experiment a while back: https://github.com/ahrefs/format-line

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: https://github.com/ahrefs/format-line/blob/master/test/run.t

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!

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 :)

Experimental tools for migrating from Lwt to Eio

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.

First alpha release of OCaml 5.5.0

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 https://github.com/ocaml/ocaml/blob/trunk/release-info/introduction.md.

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

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:

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 <switch_name> ocaml-variants.5.5.0~alpha1+options <option_list>

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]

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:

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 <DIR> 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

Running Real Docker Containers in OCaml Tests

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.

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

Griffin announced

Hi guys,

https://github.com/GriffinCanCode/Callosum

https://pypi.org/project/callosum-dsl/

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

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.

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:

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.