Mach v0.3 has been released! For all the details check out the announcement

Ziggified Freetype 2 bindings with zero-fuss installation, cross compilation, and more.

Getting started

Create a build.zig.zon in your project (replace LATEST_COMMIT with the latest commit hash):

    .name = "mypkg",
    .version = "0.1.0",
    .dependencies = .{
        .mach_freetype = .{
            .url = "",

Run zig build in your project, and the compiler will instruct you to add a .hash = "..." field next to .url:

note: expected .hash = "12209838fcfb7a77d2d6931efdc7448c033a1b7dad11d082c94bbeeba9d1038cd311",

Next, use the dependency in your build.zig:

const std = @import("std");

pub fn build(b: *std.Build) void {
    const target = b.standardTargetOptions(.{});
    const optimize = b.standardOptimizeOption(.{});

    const exe = b.addExecutable(.{
        .name = "tmp",
        // In this case the main source file is merely a path, however, in more
        // complicated build scripts, this could be a generated file.
        .root_source_file = .{ .path = "src/main.zig" },
        .target = target,
        .optimize = optimize,

    // Use mach-freetype
    const mach_freetype_dep = b.dependency("mach_freetype", .{
        .target = target,
        .optimize = optimize,
    exe.root_module.addImport("mach-freetype", mach_freetype_dep.module("mach-freetype"));
    exe.root_module.addImport("mach-harfbuzz", mach_freetype_dep.module("mach-harfbuzz"));

    const run_cmd = b.addRunArtifact(exe);
    const run_step = b.step("run", "Run the app");

You can now use it in your src/main.zig file:

const freetype = @import("mach-freetype");
const harfbuzz = @import("mach-harfbuzz");

Ran into trouble?

Triple-check you followed the build.zig.zon instructions correctly, it’s easy to mess that part up.

Feel free to join the Mach Discord community for help.