Contact Info

sean [at] coreitpro [dot] com gpg key

Mastodon

sc68cal on Libera

Managing Static Assets With Zig Build

I’m continuing to experiment with building a web application in Zig, and one of the things that any lazy back-end software engineer will reach for when it comes time to build an HTML frontend.

However, I don’t really care to pull in all of nodejs and npm in order to manage bootstrap.

So I thought, why not try and see if I can manage it via Zig’s built in build system?

The first thing was to fetch bootstrap and add it to my build.zig.zon file:

zig fetch --save=bootstrap https://github.com/twbs/bootstrap/releases/download/v5.3.3/bootstrap-5.3.3-dist.zip

This will end up adding the following to your build file.

diff --git a/build.zig.zon b/build.zig.zon
index 56f2c0f..29f41bb 100644
--- a/build.zig.zon
+++ b/build.zig.zon
@@ -40,6 +40,10 @@
             .url = "https://github.com/jetzig-framework/jetzig/archive/refs/heads/main.zip",
             .hash = "jetzig-0.0.0-IpAgLZ4RDwDIhgF_bgxiO6qxCRSdtUAq4y4WHTtO_zQc",
         },
+        .bootstrap = .{
+            .url = "https://github.com/twbs/bootstrap/releases/download/v5.3.3/bootstrap-5.3.3-dist.zip",
+            .hash = "N-V-__8AADmEhAChEbTwQ1bJaHsF6OJ10mMavacv-kDlUYZR",
+        },
     },

The next step was to figure out how to extract the zip during the build and place it somewhere in the build output, so it could be used by later build steps. I came across this post which helped me move further. Adding the following to your build.zig will extract the zip into zig-out during the build phase, in the static directory along side the executable.

    const bootstrap = b.dependency("bootstrap", .{});
    const install_step = b.addInstallDirectory(.{
        .source_dir = bootstrap.path("."),
        .install_dir = std.Build.InstallDir{ .custom = "static" },
        .install_subdir = ".",
    });
    exe.step.dependOn(&install_step.step);

Now, if you are using jetzig you will want to have your build file set up a little differently, to extract the files into the public folder that jetzig uses for serving static content, and place it at the correct location above the jetzig.jetzigInit call so that it gets build into the server executable.

     // Bootstrap js/css
    const bootstrap = b.dependency("bootstrap", .{});
    const install_step = b.addInstallDirectory(.{
        .source_dir = bootstrap.path("."),
        .install_dir = std.Build.InstallDir{ .custom = "../public/" },
        .install_subdir = ".",
    });
    exe.step.dependOn(&install_step.step);
    try jetzig.jetzigInit(b, exe, .{});