CLI tool
mirage/mirage avatar
mirage/mirage

MirageOS and the mirage CLI: building OCaml unikernels

MirageOS is a library operating system that constructs unikernels

2,995 stars276 forksOCamlISC

At a glance

What is it?
The mirage command-line tool wraps the configuration and build steps that turn OCaml code into a standalone unikernel for Xen, KVM, BHyve or VMM. Here is what the repository documents, and where the documentation stops.
Who is it for?
Adopt mirage if you already write OCaml and want a single specialised image for Xen, KVM, BHyve or VMM instead of a general-purpose guest. Do not adopt it if your stack is not OCaml, or if you need the documentation to cover deployment and rollback, because the README stops at dune build.
Can I use it commercially?
Yes. ISC is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 63 days ago.
What is it written in?
Mainly OCaml, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on September 29, 2026, and from our analysis. They are not legal advice.

DEEP OPEN-SOURCE ANALYSIS

What MirageOS solves, and who it is written for

A conventional application ships with an operating system underneath it: a scheduler, a filesystem, drivers, a login path, a package manager. MirageOS takes the other route. It is described in the repository as a library operating system that constructs unikernels, which means the OCaml code you write is compiled together with only the OS components it actually calls, producing a fully-standalone, specialised image. The stated targets are the Xen and KVM hypervisors and lightweight hypervisors such as FreeBSD's BHyve and OpenBSD's VMM. Public clouds named in the README include Amazon's Elastic Compute Cloud and Google Compute Engine, alongside private deployments.

The audience is therefore narrow and specific. You need to be comfortable in OCaml, because there is no other language path into this toolchain. You need a Linux, FreeBSD, OpenBSD or macOS development machine, since the README lists those as the hosts where you write and compile. If you are building a network service that should boot straight into your code, with no shell and no general-purpose userland, this is the shape of project you are looking for. If you are building something that needs a package manager at runtime, or a filesystem you can poke at interactively, the model works against you rather than for you.

config.ml, mirage configure and the build pipeline

The repository is explicit that the mirage command-line tool is a wrapper around the specialised configuration and build steps required for each supported target. That framing matters, because mirage is not a compiler and not a hypervisor manager. It is the piece that reads your description of an application and emits the code and metadata the rest of the OCaml toolchain consumes.

The README lays out four stages. First you write config.ml to describe the components of your application. Then you call mirage configure to generate the necessary code and metadata. Optionally you call make depends, which installs external dependencies and downloads Opam packages into the current dune workspace. Finally you call dune build to produce the unikernel. The ordering is not decorative: configure has to run before the dune build has anything meaningful to compile, and the dependency step exists because a unikernel's package set is decided by what config.ml declares, not by what happens to be installed globally.

The repository layout supports that reading. There is a bin/ directory for the command-line entry point, lib/ and lib_runtime/ for the library side, and a test/ directory with a functoria subdirectory, which points at the configuration layer underneath the CLI. The Makefile is short and conventional: dune build for the default target, dune clean, dune build @doc for documentation, and dune runtest plus a functoria end-to-end test for the test target. Nothing in the README describes what happens after the image exists, which is the gap worth noticing before you plan a deployment.

Installing mirage and building a first unikernel

The README states three prerequisites: an OCaml compiler at 4.13.0 or higher, the Opam source package manager at 2.1.0 or higher, and a host that can compile for your target. For Xen kernels that means an x86_64 or armel Linux host. For the solo5 and userlevel versions, FreeBSD, OpenBSD or macOS X are listed instead. Install the CLI through Opam and confirm the version:

bash
opam install mirage
mirage --version

The README says this should display at least version 4.0.0. If it prints something older, the Opam switch you are in is not the one the install landed in.

With the tool present, the workflow is the four stages the README describes. Write a config.ml describing your components, then run configure, then resolve dependencies, then build:

bash
mirage configure
make depends
dune build

What you should see is generated code and metadata after the configure step, additional Opam packages pulled into the current dune workspace after make depends, and a built unikernel after dune build. The README does not print the expected output of any of these commands, so treat the absence of errors as the signal rather than a specific success message. For a fuller walkthrough the README points at the MirageOS website, and specifically at the install instructions on its wiki; it also points at the mirage-skeleton repository for simpler skeleton applications. Those are the places to go when config.ml needs to describe something the README does not show.

Where the documentation stops

The README covers installation, the four build stages, and the set of supported hosts and hypervisors. It does not document deployment. There is no section on getting the resulting image onto a hypervisor, no description of how to roll back to a previous unikernel, and no guidance on monitoring or updating a running instance. The repository's RELEASE.md file exists, but the README does not summarise its contents, so a reader cannot tell from the front page what the release process expects of them.

That gap has a practical consequence. Because a unikernel is a single specialised image rather than a mutable system, the operational questions change shape: there is no shell to log into when something misbehaves, and the usual answer of patching a running host does not apply. The README does not address any of this. It is not a defect in the code, but it is a real limit on what you can plan from the repository alone, and it means the MirageOS website and the unikernel repositories linked from the README are load-bearing rather than optional reading.

A second constraint is the host list. If your development machine is neither Linux, FreeBSD, OpenBSD nor macOS, the README offers no path. That is a smaller issue than the deployment gap, but it is a hard boundary rather than a preference.

MirageOS against a container runtime

The obvious alternative for someone weighing this project is a container runtime such as Docker, and the difference is architectural rather than a matter of degree. A container shares the host kernel and carries a userland: an init process, a shell, a package set, a filesystem you can inspect. A MirageOS unikernel, as the README describes it, is compiled into a fully-standalone, specialised image that runs under a hypervisor. There is no shared kernel and no userland beyond what your OCaml code pulls in.

That changes the operational model in both directions. A unikernel's attack surface is whatever the build included, which is the appeal. The cost is that the tooling you have built around containers (image registries, orchestration, exec into a running instance) has no direct equivalent here. The README names Xen, KVM, BHyve and VMM as the runtimes, and Amazon EC2 and Google Compute Engine as deployment targets, so the deployment path is hypervisor-shaped, not container-shaped.

The other honest comparison is writing the same service in OCaml on a normal Linux host. You keep the language and lose the specialisation, and you keep every debugging tool you already know. MirageOS is worth the trade only when the reduced image is the point, not when it is a side effect.

Maintenance, versioning and the ISC licence

The last push to the repository was on 2026-07-28, and the most recent release listed is v4.11.2 on the same date, following v4.11.1 on 2026-07-04 and v4.11.0 on 2026-05-07. The repository is not archived. The release cadence visible in those three versions is roughly monthly across the spring and summer, which tells you the project is being cut and tagged, though the README does not state a support window for older lines.

The upgrade cost is partly a property of the language. Because mirage is distributed through Opam and depends on a working OCaml compiler, upgrading the CLI interacts with your Opam switch and with the packages that make depends pulled into your dune workspace. The README does not describe an upgrade procedure or a compatibility policy between mirage versions, so the CHANGES.md file is where you would look before moving a working build forward. That file is present in the repository root.

The licence is ISC, a permissive licence. The repository carries both LICENSE.md and mirage.opam, and the README does not add conditions beyond that. What ISC means for your product is a question for your own legal review; the repository does not discuss linking, distribution or attribution requirements, and nothing here should be read as advice on those points.

Editorial conclusion

Adopt mirage if you already write OCaml and want a single specialised image for Xen, KVM, BHyve or VMM instead of a general-purpose guest. Do not adopt it if your stack is not OCaml, or if you need the documentation to cover deployment and rollback, because the README stops at dune build. Before committing, verify that your toolchain meets the stated floors (OCaml 4.13.0, Opam 2.1.0, mirage 4.0.0 or higher), that your host is one of the listed ones, and that the unikernel repositories under roburio or tarides contain something close to your workload.

Frequently asked questions

How do I install mirage?

Install it through Opam with opam install mirage, then check the version with mirage --version. The README states you need an OCaml compiler at 4.13.0 or higher and Opam at 2.1.0 or higher, and that the version command should display at least 4.0.0.

How do I use mirage to build a unikernel?

The README describes four stages: write config.ml to describe your application's components, run mirage configure to generate code and metadata, optionally run make depends to install dependencies into the current dune workspace, then run dune build.

Which hosts and hypervisors does the mirage tool support?

The README lists an x86_64 or armel Linux host for compiling Xen kernels, and FreeBSD, OpenBSD or macOS X for the solo5 and userlevel versions. The unikernels themselves run under Xen or KVM, or lightweight hypervisors such as FreeBSD's BHyve and OpenBSD's VMM.

What language do I write MirageOS unikernels in?

OCaml. The repository describes MirageOS as a library operating system that constructs unikernels, and the mirage CLI wraps the configuration and build steps for the OCaml toolchain. The README gives no path for other languages.

Does the mirage README explain how to deploy the built unikernel?

No. The README stops at dune build and points to the MirageOS website for documentation, walkthroughs and tutorials. It does not document deployment, rollback or operating a running unikernel.

Official sources

  1. License: ISC
  2. mirage/mirage on GitHub
  3. Project website
  4. README
  5. Releases
For maintainers

Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/mirage-mirage.svg)](https://hysenlabs.com/projects/mirage-mirage)
Community notes

Community notes