Libraries

for Zig 0.15.2 Buy

Libraries

IJust like the functions we define ourselves, all the functions we call in Zig - including those from the standard library - have their declarations in the source code itself. For example, the print function that we use so often…

We can find its implementation in the path where we downloaded Zig. In the std subdirectory, we will find the debug.zig file.

In that file, we will find the definition of the function:

  /// Print to stderr, silently returning on failure.

  /// ...

  pub fn print(comptime fmt: []const u8, args: anytype) void { //...

If we wanted to modify that function - or any other - even if we detect a bug or want to create our own version, we are free to do so.

Since our declarations for modeling towers, the river, and so on are growing, we can write them in our own file, for example:

hydro.zig

const std = @import("std");

// a tower with oscillating buckets

pub const HydroTower = struct {

    const N_EFFICIENCY_PER_METER: f32 = 0.91;

    n_efficiency_per_meter: ?f32, // optional

    n_height: f32,

    pub fn lift_water(

        self: *const HydroTower,

        n_input: ?f32,

    ) struct { f32, f32 } {

        return .{

            (n_input orelse 0) * std.math.pow(

                f32,

                self.n_efficiency_per_meter orelse

                    HydroTower.N_EFFICIENCY_PER_METER,

                self.n_height,

            ),

            self.n_height,

        };

    }

    // simulate a tower height built between 3.5 and 5m

    pub fn get_height_btw(n_min: f32, n_max: f32) f32 {

        return round2(get_rand(

            n_min,

            n_max,

        ));

    }

};

// river flow carried to the tower

pub const WaterFlow = struct {

    n_liters_per_second: f32,

    pub fn get_fps(self: *const WaterFlow) f32 {

        const n_min = self.n_liters_per_second * 0.90;

        return round2(get_rand(

            n_min,

            self.n_liters_per_second,

        ));

    }

};

// inline function to round to 2 decimals

pub inline fn round2(n_x: f32) f32 {

    return @floor(100 * n_x) / 100;

}

// inline function to get a random number between n_min and n_max

inline fn get_rand(n_min: f32, n_max: f32) f32 {

    return std.Random.float(std.crypto.random, f32) *

        (n_max - n_min) + n_min;

}

This file will not be executable on its own, but it contains the functions and structures we have defined and can be used by other Zig files. Just as we import print from std.debug, we can now reuse our own functions in the same way. This way, we do not have to define the same code over and over again, making our programs significantly shorter. We have modularized the program.

For a function or structure declared in a library to be callable from outside, we must write the reserved word pub in front of its declaration:

  pub const WaterFlow = struct {

o

  pub inline fn round2(n_x: f32) f32 {

However, this function will be unreachable from outside the file that contains it:

  inline fn get_rand(n_min: f32, n_max: f32) f32 {

Import and use the module like this:

const std = @import("std");

const std = @import("std");

const print = std.debug.print;

const ArrayList = std.ArrayList;

// import the hydro library we wrote

const hydro = @import("./hydro.zig");

const WaterFlow = hydro.WaterFlow;

const HydroTower = hydro.HydroTower;

// if we have not imported a function

// explicitly

// will have to call it using the

// library prefix

hydro.round2(n_riverflow)

Inline functions
Dynamic lists - ArrayList
© 2025 - 2026 Zen of Zig