Building a personal library of zig-native utilities?

How do I specify the location of my personal utilities files on system-wide


  1. I have a collection of various utility functions that I use across
    a variety of different (independent) programs.

  2. To keep a flat directory structure (easier for navigation/overview),
    I avoid the “zig init-exe” step, since it creates the cumbersome build.zig,
    src/, and zig-out/ subdirectories.

  3. The preference is just to use “zig build-exe myfile.zig” when developing
    and experiment with it by typing “myfile”. Pretty simple.


Suppose I keep all of my personal utilities in separate files in a directory “~/ZigUtils”.

Without needing a separate “build.zig” file for every program that I
develop, How I do tell my program under develop to find the

I have tried using the lines in my main.zig file:

  "const util_x = @import("~/ZigUtils/util_x.zig"
  "const util_x = @import("../../ZigUtils/util_x.zig"

But always get the dreaded “error: import of file outside package path”.

Probably I need to add “~/ZigUtils” to my package path. How do I do this
on a system-wide basis? (so I do not need separate build.zig files for each

There is likely some editing of the “/usr/local/zig/build.zig” to be done.
But, I do not see the solution.

Any suggestions?

Thanks for all hints here.

PS I have read Felix “xq” Qusissner’s excellent series on “zig build explained”
where he details including the build process, and how to deal with “c” libraries,
etc. But, I couldn’t figure out how to develop and maintain my own “zig native”
personal utility library. (This is the real, underlying question for me.)

If you really must do this, and without going through build.zig for whatever reason, then you can define it as your own package and import relative to that:

$ grep ZigUtils whatever.zig
const util_x = @import("ZigUtils").util_x;

$ zig run --pkg-begin ZigUtils ~/ZigUtils --pkg-end whatever.zig
$ zig build-exe --pkg-begin ZigUtils ~/ZigUtils --pkg-end whatever.zig && ./whatever

I don’t think you want to do this as a system-wide default. Please define a build.zig for your projects when they outgrow the “toy” stage. :slight_smile:

1 Like

Hello jmc,

Thanks kindly for your reply. I have a better perspective now. Also, I should clarify
my poorly written original post.

The use of a build.zig process to create the toolbox of utility functions is quite fine. This toolbox is a long-term evolving set of tools to be used in a broad variety of settings.

The real goal is when experimenting with smaller code snippets (unrelated to these utilities) I hope to be able to enjoy quick access to my personal Zig-utils with minimal overhead effort.

A graceful solution would mirror what we already write when using the std library:

const myutils = @import(“myZigUtilities”);

This single line entry into small experiment source files (without need of a build.zig file and directory tree, etc) would be delightful.

It is for these quick one-off experiments that I wish to avoid the build.zig frictions, not the utilities module.

Is there a good method to achieve this simplicity?

Thanks, and Cheers,

The form @import("blah") is in fact an import for a package named blah, so the above approach is what you want. Your package should have a file with the same name of the package which exports the definitions that should be made available to the outside world.

For instance, here’s the entry point for the std package:


Excellent! Thanks for steering me in the right direction on this here!


Here’s a fixed version of @jmc’s excellent answer:

$ grep ZigUtils whatever.zig
const zig_utils = @import("ZigUtils");

$ zig run --pkg-begin ZigUtils ~/ZigUtils/zig_utils.zig --pkg-end whatever.zig
$ zig build-exe --pkg-begin ZigUtils ~/ZigUtils/zig_utils.zig --pkg-end whatever.zig && ./whatever

A pkg definition has to point to a source file instead of a directory.

1 Like


Tack! Thanks for the reply.

The zig build process is making more sense as I learn it, actually is rather nice!