A production-grade runtime .env library for Zig - parsing, interpolation, validation, and serialization.
Documentation | API Reference | Quick Start | Comparison | Contributing
env.zig is a production-grade runtime .env file library for Zig, providing everything needed to manage application configuration - parsing .env files, variable interpolation, schema validation, serialization, type-safe accessors, and modular architecture.
Tip
If you build with env.zig, make sure to give it a star.
Related Zig projects:
- For env.zig (.env parsing), check out env.zig.
- For TUI support, check out tui.zig.
- For ZON file format support, check out zon.zig.
- For spinners/loading/progress bar support, check out loaders.zig.
- For MCP support, check out mcp.zig.
- For args parsing support, check out args.zig.
- For HTTP client/server support, check out httpx.zig.
- For API framework support, check out api.zig.
- For web framework support, check out zix.
- For archive/compression support, check out archive.zig.
- For compression file format support, check out zigx.
- For file downloading support, check out downloader.zig.
- For update checker/auto-updater support, check out updater.zig.
- For numerical computing support, check out num.zig.
- For logging support, check out logly.zig.
- For data validation and serialization support, check out zigantic.
Features (click to expand)
| Feature | Description | Documentation |
|---|---|---|
.env File Parsing |
Load and parse .env files with comments, quotes, empty values, and inline comments. |
https://muhammad-fiaz.github.io/env.zig/guide/getting-started |
| Variable Interpolation | ${VAR} syntax with circular dependency detection and configurable max depth. |
https://muhammad-fiaz.github.io/env.zig/guide/interpolation |
| Escape Sequences | \n, \t, \r, \\, \", \', \` in double-quoted values. |
https://muhammad-fiaz.github.io/env.zig/guide/getting-started |
| Schema Validation | Define schemas with required fields, types, and custom validators. Errors for required, warnings for optional. | https://muhammad-fiaz.github.io/env.zig/guide/validation |
| Built-in Validators | required, boolean, integer, float, url, email, ipv4, hostname, port, range, minLength, maxLength, oneOf. |
https://muhammad-fiaz.github.io/env.zig/api/validators |
| Type-Safe Accessors | get, getString, getBool, getInt, getFloat, getEnum, getList - automatic parsing and type conversion. |
https://muhammad-fiaz.github.io/env.zig/api/env |
| Serialization | Write configurations back to .env format with key sorting, value quoting, and trailing newlines. |
https://muhammad-fiaz.github.io/env.zig/guide/serialization |
| Insertion Order | Guaranteed key iteration order (unlike std.process.Environ). |
https://muhammad-fiaz.github.io/env.zig/api/env |
| Cache | Built-in key-value cache for frequently accessed values. | https://muhammad-fiaz.github.io/env.zig/api/env |
| Iterator | Iterate over entries with next, peek, reset, skip, remaining, collect. |
https://muhammad-fiaz.github.io/env.zig/api/env |
| Config Builder | Chainable .with() pattern for configuration customization. |
https://muhammad-fiaz.github.io/env.zig/api/config |
| Modular Architecture | Parser, lexer, tokenizer, interpolation, schema, validator, serializer, writer, cache, iterator - all in separate files. | https://muhammad-fiaz.github.io/env.zig/api/env |
| Allocator-Aware | Every allocation has a matching deinit, no leaks. |
https://muhammad-fiaz.github.io/env.zig/guide/getting-started |
| Zero Global State | No OOP, no singletons, fully composable. | https://muhammad-fiaz.github.io/env.zig/guide/getting-started |
| Multiple File Loading | Load multiple .env files in order with override control. |
https://muhammad-fiaz.github.io/env.zig/api/env |
| Clone & Merge | Deep copy and merge Env instances. |
https://muhammad-fiaz.github.io/env.zig/api/env |
| Error Handling | Graceful handling of corrupted files, missing keys, invalid formats with rich diagnostics. | https://muhammad-fiaz.github.io/env.zig/guide/getting-started |
| No External Dependencies | Pure Zig implementation for maximum portability. | https://muhammad-fiaz.github.io/env.zig/guide/getting-started |
Prerequisites and Supported Platforms (click to expand)
Before using env.zig, ensure you have the following:
| Requirement | Version | Notes |
|---|---|---|
| Zig | 0.16.0+ | Download from ziglang.org |
| Operating System | Windows 10+, Linux, macOS | Cross-platform support |
env.zig is validated on these architectures:
| Platform | x86_64 (64-bit) | aarch64 (ARM64) | x86 (32-bit) |
|---|---|---|---|
| Linux | Yes | Yes | Yes |
| Windows | Yes | Yes | Yes |
| macOS | Yes | Yes (Apple Silicon) | No |
Zig makes cross-compilation easy. Build for any target from any host:
# Build for Linux ARM64 from Windows
zig build -Dtarget=aarch64-linux
# Build for Windows from Linux
zig build -Dtarget=x86_64-windows
# Build for macOS Apple Silicon from Linux
zig build -Dtarget=aarch64-macos
# Build for 32-bit Windows
zig build -Dtarget=x86-windowszig fetch --save=env https://github.com/muhammad-fiaz/env.zig/archive/refs/tags/0.0.1.tar.gzUse the latest development version from the main branch.
zig fetch --save=env git+https://github.com/muhammad-fiaz/env.zig.gitAdd the dependency to your build.zig.zon file.
.dependencies = .{
.env = .{
.url = "https://github.com/muhammad-fiaz/env.zig/archive/refs/tags/0.0.1.tar.gz",
.hash = "...", // Run `zig fetch --save=env <url>` to generate the hash.
},
},Clone the repository locally.
git clone https://github.com/muhammad-fiaz/env.zig.git
cd env.zig
zig buildTo use a local checkout from another project, add a path dependency to your build.zig.zon:
.dependencies = .{
.env = .{
.path = "../env.zig",
},
},After adding the dependency, import the module in your build.zig:
const env_dep = b.dependency("env", .{
.target = target,
.optimize = optimize,
});
exe.root_module.addImport("env", env_dep.module("env"));const std = @import("std");
const Io = std.Io;
const env_mod = @import("env");
pub fn main(init: std.process.Init) !void {
const io = init.io;
const allocator = init.gpa;
var env = env_mod.Env.init(allocator, .{});
defer env.deinit();
// Load from file
try env.load(".env");
// Or parse from string
try env.parseString("HOST=localhost\nPORT=8080\n");
// Read values with type-safe accessors
const host = env.get("HOST") orelse "localhost";
const port = env.getInt(u16, "PORT") orelse 3000;
const debug = env.getBool("DEBUG") orelse false;
// Print to stdout
var stdout_buffer: [0x100]u8 = undefined;
var stdout_writer = Io.File.stdout().writer(io, &stdout_buffer);
const stdout = &stdout_writer.interface;
try stdout.print("host={s} port={d} debug={}\n", .{ host, port, debug });
try stdout.flush();
}var env = env_mod.Env.init(allocator, .{
.strict = true, // Fail on syntax errors
.interpolate = true, // Enable ${VAR} interpolation
.trim = true, // Trim whitespace from keys/values
.override = true, // Override existing values when loading multiple files
.sort_keys = true, // Sort keys when serializing
.quote_spaces = true, // Quote values containing spaces
});const schema = env_mod.schema.Schema.init(&.{
.{
.key = "DATABASE_URL",
.required = true,
.validators_list = &.{ validators.required, validators.url },
.description = "Database connection URL",
},
.{
.key = "PORT",
.required = true,
.validators_list = &.{ validators.required, validators.integer, validators.port },
.description = "Server port",
},
.{
.key = "LOG_LEVEL",
.required = false,
.default_value = "info",
.validators_list = &.{validators.oneOf(&.{ "debug", "info", "warn", "error" })},
.description = "Logging level",
},
});
const errors = schema.validate(&env.entries);
if (errors.len > 0) {
for (errors) |err| {
std.debug.print("{s}: {s}\n", .{ err.key, err.message });
}
}// Serialize to .env string
const output = try env.serialize();
defer allocator.free(output);
// Save to file
try env.save("output.env");// Deep copy
var cloned = try env.clone();
defer cloned.deinit();
// Merge (other overrides self)
try env.merge(&other_env);GREETING=hello
MESSAGE=${GREETING} world// MESSAGE resolves to "hello world"
const msg = env.get("MESSAGE");The examples/ directory contains comprehensive, runnable examples:
- Basic - Set/get values, type-safe accessors, iteration, serialization.
- Validation - Schema validation with built-in validators.
- Serialization - Serialize to
.envformat with sorting and quoting.
To run any example:
zig build example
zig-out/bin/basic_example
zig-out/bin/validation_example
zig-out/bin/serialization_exampleValidate host functionality and cross-target compatibility:
# Host runtime validation
zig build test
# Generate native documentation
zig build docs
# Run examples
zig build example
# Check formatting
zig fmt --check src/| Feature | std.process.Environ |
env.zig |
|---|---|---|
| Source | OS process env vars | .env files + manual entries |
| File Parsing | No | Yes |
| Variable Interpolation | No | Yes |
| Schema Validation | No | Yes |
| Type-Safe Accessors | No | Yes |
| Insertion Order | OS-dependent | Guaranteed |
| Serialization | No | Yes |
| Cache | No | Yes |
| Config Options | OS-specific | 14+ options |
| Multiple Files | N/A | Yes |
| Override Control | N/A | Yes |
| Strict Mode | N/A | Yes |
| Clone/Merge | Clone only | Both |
| Allocator-Aware | Yes | Yes |
See the full comparison.
Contributions are welcome! Please:
- Fork the repository
- Create a feature branch
- Add tests for new functionality
- Ensure all tests pass:
zig build test - Ensure formatting is clean:
zig fmt --check src/ - Submit a pull request
See CONTRIBUTING.md for detailed guidelines.
MIT License - see LICENSE for details.