h2o-zig

libh2o packaged for Zig with cross-compilation support for Linux and macOS.

doc status: maturing nixbot

This is libh2o, packaged for Zig with cross-compilation support for Linux and macos.

  • all dependencies are statically linked into the output

  • output is a static library (.a) for embedding into other projects

The intended usage is for building language bindings and FFI wrappers that need to expose all h2o and SSL symbols in a final shared library.

Included h2o features:

features explicitly excluded:

  • mruby

  • memcached integration

  • redis integration

  • libuv

Supported targets:

  • x86_64-linux

  • aarch64-linux

  • x86_64-macos

  • aarch64-macos

Project status: Maturing.

Quick start

  1. Install zig

  2. zig build or zig build -Dtarget=<target> (where <target> is from the above list)

Prerequisites

You need the following installed:

  • Zig 0.16.0

  • Perl (for an h2o build step)

If you have nix you can use the dev shell provided by the flake in this repo.

Use as a dependency

Add this package to your build.zig.zon:

zig init # if you don't have a build.zig already
zig fetch --save git+https://github.com/outskirtslabs/h2o-zig.git

Then link the exported h2o-evloop artifact in build.zig:

const h2o = b.dependency("h2o", .{
    .target = target,
    .optimize = optimize,
});
const h2o_lib = h2o.artifact("h2o-evloop");
your_exe.root_module.linkLibrary(h2o_lib);

If your project only links the archive, linkLibrary is enough. If it compiles C code that includes H2O headers, also expose the artifact’s public headers and disable libuv in H2O’s public configuration:

your_exe.root_module.addIncludePath(h2o_lib.getEmittedIncludeTree());
your_exe.root_module.addCMacro("H2O_USE_LIBUV", "0");

The exported include tree contains BoringSSL and wslay headers. C and C++ code can include these headers directly. Zig’s @cImport cannot parse some BoringSSL macros included by h2o.h, so Zig code using the BoringSSL backend needs handwritten or generated Zig declarations, or must put its H2O-facing code in a C source file.

Build Options

Pass these options to b.dependency:

  • .@"use-aegis" = <bool> - Enable AEGIS AEAD ciphers (default: false)

For example:

const h2o = b.dependency("h2o", .{
    .target = target,
    .optimize = optimize,
    .@"use-aegis" = true,
});
your_exe.root_module.linkLibrary(h2o.artifact("h2o-evloop"));

Brotli and Zstandard support are always enabled through external Zig dependencies built with position-independent code.

Redis and memcached integrations are unsupported. Some related upstream sources remain in the archive to avoid downstream patches.

Cross-Compilation to macOS

When cross-compiling from Linux to macOS targets (x86_64-macos or aarch64-macos), the build requires the APPLE_SDK_PATH environment variable to be set. This points to the macOS SDK that provides system headers and libraries.

Using Nix (Recommended)

The provided nix flake automatically sets up APPLE_SDK_PATH when you enter the development shell:

nix develop
zig build -Dtarget=aarch64-macos
zig build -Dtarget=x86_64-macos

Manual Setup

If not using nix, you’ll need to obtain a macOS SDK and set the environment variable:

export APPLE_SDK_PATH=/path/to/MacOSX.sdk
zig build -Dtarget=x86_64-macos

The SDK must contain usr/include with macOS system headers. Without this, cross-compilation to macOS will fail with an error about the missing APPLE_SDK_PATH environment variable.

Note: Cross-compilation to macOS from macOS does not require APPLE_SDK_PATH as the system SDK is used automatically.

Hacking on H2O

This project also serves as a reproducible dev environment for h2o thanks to the nix flake’s devshell.

Simply activate the nix devshell then:

git clone https://github.com/h2o/h2o.git h2o
cd h2o
cmake -B build -S .  -DDISABLE_LIBUV=ON -DWITH_MRUBY=OFF
cmake --build build -j$(nproc)
cmake --build build --target check

Building picotls (with AEGIS support)

To build and test picotls (the TLS library used by h2o) with AEGIS cipher support:

git clone https://github.com/h2o/picotls.git vendor/picotls
cd vendor/picotls
nix develop ../   # enter devshell from picotls directory

cmake -B build -S . \
  -DWITH_AEGIS=ON \
  -DCMAKE_PREFIX_PATH=$CMAKE_PREFIX_PATH \
  -DAEGIS_INCLUDE_DIR=$AEGIS_INCLUDE_DIR

cmake --build build -j$(nproc)

./build/test-openssl.t

License: MIT License

h2o-zig is distributed under the MIT.

Copyright © 2025-2026 Casey Link casey@outskirtslabs.com

Binary distributions (JAR files on Clojars and GitHub releases) may bundle the following third-party projects:

  • h2o is licensed under the MIT License and copyright DeNA Co., Ltd., Kazuho Oku, and contributors.

  • brotli is licensed under the MIT License and copyright (c) 2009, 2010, 2013-2016 by the Brotli Authors.

  • zstd is licensed under the BSD License and copyright (c) Meta Platforms, Inc.

  • BoringSSL is licensed under the Apache 2.0 License and copyright a bunch of folks

  • libaegis is licensed under the MIT license and copyright (c) 2023-2026 Frank Denis