zig-config: A Lightweight .env/.ini Library for Zig

Hello Everyone!

I’ve been working on a lightweight config library for Zig called zig-config. It is to made to handle configuration files in .env and .ini formats. It has features like variable substitution, section handling, merging, and serialization.

I am building this to learn and get into zig since I never really got into languages like rust or C but love the way zig types. So please give any feedback you got!

Key Features:

  • .env and .ini Parsing: Supports comments, quoted values, empty lines, and section headers.

  • Variable Substitution: Handles patterns like ${VAR}, ${VAR:-fallback}, ${VAR:+val}, and escaped variables like \$HOME.

  • Typed Accessors: Has getInt(), getFloat(), getBool() for type-safe retrieval.

  • Section Handling: Go into specific sections using getSection("section_name").

  • Merging Configs: Merge configs with strategies like overwrite, skip_existing, or error_on_conflict.

  • Serialization: Write configs back to .env or .ini files.

  • Error Handling: Comprehensive error types like InvalidPlaceholder UnknownVariable, etc.

Usage Example:

Loading a .ini file:


; settings.ini

[database]

host=localhost

user=root

port=5432


const cfg = try Config.loadIniFile("settings.ini", allocator);

defer cfg.deinit();

const host = cfg.get("database.host") orelse "localhost";

const db = try cfg.getSection("database", allocator);

defer db.deinit();

const user = db.get("user") orelse "root";

Variable substitution:


HOST=localhost

PORT=8080

URL=http://${HOST}:${PORT}

FALLBACK=${NOT_SET:-default}


const url = try cfg.get("URL"); // http://localhost:8080

const fallback = try cfg.get("FALLBACK"); // "default"

Roadmap:

  • Integration with std.process.getEnvMap() for process env loading. → just learned about this.

  • Support for nested substitutions like ${A:-${B:-fallback}}.

  • Enhanced error handling for circular references.

  • Generic accessor: get(T: type, key, allocator) ?T.

  • Fuzz testing for .env and .ini parsing.

  • Maybe: Add support for additional config formats (e.g. JSON, TOML?).

I am new to Zig and would greatly appreciate any feedback, suggestions, or contributions. Feel free to check out the repo here: GitHub - Niek-HM/zig-config: Simple zig library that handle's .env / .ini files

Looking forward to your thoughts!

4 Likes

I quite like the API (imo one of the hardest tasks when writing a library, besides good naming) and I will keep this library in mind for a project I want to do at some point™.

Since TOML is these days used quite a lot on Linux (mainly in the systemd suite), this would be a nice addition and your Merging features immediately made me think of it.

So it would be a nice (and useful) addition for writing systemd-generators.

But as with anything Open Source, if you want to do this is up to you.

I guess you mean with that that the Config structs can create an or load from an EnvMap?

I have not yet read into this so it might not be right for me, but I saw someone comment that it might be useful in projects using .env’s… Will prob look into it this weekend to see if it is worth using.

As for TOML, I want to add them, but first I want to finish up the .env and .ini, to have the main features down and then expand.

Regarding additional formats: if you use an off-the-shelf YAML parser, you get JSON support for free too (YAML is a superset of JSON weirdly enough).

Lol, it does look really similar. Good to know for when I start working on it!