Library / SDK
hermit-os/kernel avatar
hermit-os/kernel

Hermit links a Rust unikernel into your application as a static library

A Rust-based, lightweight unikernel.

1,508 stars133 forksRustApache-2.0

At a glance

What is it?
hermit-kernel is a Rust library operating system that is normally linked statically into an application rather than booted as a standalone image, with drivers for virtio, TCP, DHCP and ACPI behind Cargo features. It suits teams running small compute instances on virtualisation, and it is a kernel you compile against rather than a distribution you install.
Who is it for?
Adopt hermit-kernel if you are running a small, self-contained compute workload on a virtual machine and want an operating system that is linked into the binary rather than installed alongside it. Do not adopt it if you need a general purpose OS, a shell, a package manager, or a kernel that boots from conventional media, because Hermit is a library OS with no userland of that kind.
Can I use it commercially?
Yes. Apache-2.0 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 8 days ago.
What is it written in?
Mainly Rust, according to GitHub's language statistics.

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

Editorial analysis

The kernel is linked as a static library, which is the whole model

hermit-kernel is the kernel of the Hermit unikernel project, and the description in the package manifest is precise about what that means: a Rust-based library operating system.

The README states the usual case directly. Usually the kernel will be linked as a static library to your applications. There is no disk image, no boot loader on disk in the usual sense, and no operating system installed next to your binary. The kernel code becomes part of the application image, and what you ship is one artefact.

That changes what an operating system is for. A conventional kernel serves many processes and provides a stable interface that programs are written against, and the kernel has to be conservative because anything it does wrong affects everything. A library OS is compiled for one program, so the kernel can be specialised to what that program needs, and the program can call into kernel functions directly rather than paying for a syscall boundary.

The two application paths are separate repositories. For Rust applications the instructions are in hermit-rs, and for C and C++ applications they are in hermit-c. The C and C++ path is enabled by a Cargo feature, newlib, which enables support for C and C++ applications via Hermit's Newlib port.

The package manifest also sets a name for the library, hermit, and the version is 0.13.0 with edition 2024. The keywords are unikernel and libos, and the category is os.

The upstream project is broader than this repository. The Hermit project page is hermit-os.org, the documentation is at hermit-os.github.io/kernel, and there is a Zenodo DOI badge for citing the kernel.

cargo xtask builds the standalone static library for three architectures

The standalone build path exists for cases where you want libhermit.a rather than a linked application, and it is a cargo xtask invocation:

sh
cargo xtask build --arch x86_64

On completion the script prints the path of libhermit.a. The architecture argument is not limited to one value: for aarch64 you replace x86_64 by aarch64, and for riscv64 you use riscv64. So the kernel targets three architectures, which is the practical reach of the project across cloud instance types and embedded boards.

The xtask pattern is worth a sentence, because it appears across Rust projects. A directory named xtask/ at the repository root holds a separate Cargo package with its own binary, and cargo xtask is cargo's mechanism for running that binary as a subcommand. The repository layout confirms it, with an xtask/ directory alongside src/, tests/, hermit-builtins/, hermit-macro/ and build.rs. The build.rs is what does the real linking work for the library build, and hermit-builtins/ is the set of symbols an application must provide, since a library OS has no other source of runtime services.

The requirement list is short: rustup, and nothing else. There is no kernel build system to install, no cross-compiler, no toolchain beyond the Rust one. The toolchain version is pinned in rust-toolchain.toml, and there is a clippy.toml, a rustfmt.toml, a deny.toml for dependency licence checking, and a typos.toml.

The reference to a Zenodo DOI in the README badges and a CITATION.cff file at the root both point the same way. This is a project that expects to be cited in academic and technical work, which is consistent with it being a teaching-and-research-adjacent operating system.

Cargo features decide what the kernel contains, and they are the real API

The feature list in Cargo.toml is the closest thing the kernel has to a public interface, and it is worth reading in full before you build.

The default features are acpi, dhcpv4, fsgsbase, kernel-stack, loader, pci-ids, pci, smp, tcp, uhyve, virtio-fs, virtio-net and virtio-vsock. That is a modern cloud instance profile: ACPI for power and configuration, DHCP for addressing, PCI enumeration with the pci-ids database, symmetric multiprocessing, TCP, the uhyve hypervisor, and the three virtio devices for filesystem, network and vsock.

Below the defaults sit the syscall and platform features. common-os enables multiple address spaces and makes Hermit use traditional system calls for communicating with the kernel instead of function calls, and the manifest carries a note that this feature is not complete yet. mman enables support for memory management system calls, with functions similar to sys/mman.h. newlib enables the C and C++ support described earlier. loader enables Hermit loader support, described as a bootloader that adapts to multiple platforms, which lives in its own repository.

The granularity is the point. A unikernel that includes a TCP stack, DHCP, ACPI parsing and a PCI database carries code that a particular application may never execute, and a static link means that code is in the binary whether or not it runs. Turning off dhcpv4 for an application with a hardcoded address, or dropping acpi on a platform that does not need it, shrinks the image and removes code paths nobody will exercise.

The doc comments in the manifest are written for the generated documentation, and they are unusually thorough for a feature list, with each feature explaining what it enables and linking to the relevant specification or repository.

The log filter is per module, and the default is Info

The kernel uses the lightweight log crate for printing kernel messages, and the verbosity is controlled by one environment variable, HERMIT_LOG_LEVEL_FILTER. The format follows the env_logger format but without the regex support.

You can set it per module, including submodules, with a string in the format [target][=level][,...], where the level is a string matching the name of a LevelFilter. The rules are spelled out: if the target is omitted the level is set as the global level, and if the level is omitted logs of all levels are printed for that target. A substring search pattern that will filter all modules can be provided after the target and level pairs with /<pattern>.

The example given is:

sh
HERMIT_LOG_LEVEL_FILTER="hermit::drivers::net=debug,smoltcp,error" cargo xtask build --arch x86_64

That reads as: the net driver module and its submodules at debug, everything from smoltcp at all levels, and error globally. The smoltcp target is notable, and being able to turn its logging on separately is the kind of thing that matters when you are debugging a network problem in a unikernel where you cannot attach a debugger easily.

The fallback is well defined. If the variable is not set, cannot be parsed, or does not provide a global level, a global level of LevelFilter::Info is used by default. So the kernel is quiet enough by default to be usable in production and loud enough to show you what it is doing.

There is a subtlety the README warns about. Although the logger only prints the name of the lowest level for the kernel modules, the match filter requires paths to start from the root, in the format hermit::MODULE_NAME::SUBMODULE_NAME. A filter that looks right but is relative to the wrong root will silently match nothing, and that is the kind of detail that costs an hour.

The kernel descends from teaching OS projects, and it is dual licensed

The credits section names the lineage, and it is short and specific. The kernel is derived from three sources: Philipp Oppermann's series of blog posts, Erik Kidd's toyos-rs which is itself an extension of Philipp Oppermann's kernel, and the Rust-based teaching operating system eduOS-rs.

That is worth pausing on, because it says something about the shape of the project. A kernel that grew out of a blog tutorial series and a teaching OS is a project with an educational lineage, and the topics on the repository confirm it, with osdev and rust-lang among the tags. Hermit is a research and teaching oriented unikernel that also happens to be usable in production, rather than a product.

The licence is a dual one. The README says licensed under either of the Apache License, Version 2.0, with the LICENSE-APACHE file, or the MIT license, with the LICENSE-MIT file, at your option. The package manifest records it as MIT OR Apache-2.0, and the README badge shows MIT/Apache-2.0.

The contribution terms are spelled out too. Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions. That is the standard dual-licensing clause and it means the licence choice is settled for contributors, which saves a negotiation per patch.

The release record is recent and regular. The tags are 0.13.2 on 2026-03-13, 0.13.1 on 2026-03-11 and 0.13.0 on 2026-02-25, and the repository is not archived with the last push on 2026-10-15. Note that the manifest version is 0.13.0 while the latest tag is 0.13.2, which is the usual situation where the main branch carries unreleased fixes.

Development happens on the hermit-os/kernel repository, and the README asks contributors to create their own fork, send a pull request, and chat on Zulip, where the project has its own channel.

Editorial conclusion

Adopt hermit-kernel if you are running a small, self-contained compute workload on a virtual machine and want an operating system that is linked into the binary rather than installed alongside it. Do not adopt it if you need a general purpose OS, a shell, a package manager, or a kernel that boots from conventional media, because Hermit is a library OS with no userland of that kind. Before you start, confirm your target architecture is x86_64, aarch64 or riscv64, read the feature list in Cargo.toml to see what your build will and will not include, and note that the kernel version in Cargo.toml is 0.13.0 while the latest release tag is 0.13.2.

Frequently asked questions

What is hermit-kernel and how is it used?

It is the kernel of the Hermit unikernel project, described in the package manifest as a Rust-based library operating system. Usually the kernel will be linked as a static library to your applications, with Rust applications using hermit-rs and C or C++ applications using hermit-c.

How do I build the Hermit kernel standalone?

Run cargo xtask build --arch x86_64, and the script prints the path of libhermit.a when it finishes. For aarch64 you replace x86_64 by aarch64, and for riscv64 you use riscv64. The only stated requirement is rustup.

How do I control the kernel log verbosity?

Set the HERMIT_LOG_LEVEL_FILTER environment variable, which follows the env_logger format without regex support. You can set it per module with [target][=level][,...], omit the target for a global level, omit the level for all levels of a target, and append /<pattern> for a substring filter. The default global level is LevelFilter::Info.

Which Cargo features does the Hermit kernel enable by default?

The default features are acpi, dhcpv4, fsgsbase, kernel-stack, loader, pci-ids, pci, smp, tcp, uhyve, virtio-fs, virtio-net and virtio-vsock. Optional features include common-os for multiple address spaces and traditional syscalls, mman for memory management syscalls, and newlib for C and C++ applications.

What licence is the Hermit kernel under?

It is dual licensed, at your option, under the Apache License 2.0 with the LICENSE-APACHE file or the MIT license with the LICENSE-MIT file. Contributions are dual licensed the same way unless the contributor states otherwise.

Official sources

  1. hermit-os/kernel on GitHub
  2. License: Apache-2.0
  3. Project website
  4. README
  5. Releases
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/hermit-os-kernel.svg)](https://hysenlabs.com/projects/hermit-os-kernel)

Was this useful?