1/velikoss/dotenv-zig v0.16
.env for Zig
dotenv zig 0.15.0
- dotenv is a super simple single file zig library for parsing a
.envfile. - implementation is < 100 lines
- Support for key-value pairs separated by
=in the.envfile. - trims trailing spaces in key and values
- values in double or single quotes get stripped: "myvalue" -> myvalue
- does not check keys for syntax correctness
- dupes the key-values into a hashmap, so the input buffer may get deallocated without problems
- Process environment variable support - automatically falls back to process environment when key is not found in .env file
- Required environment variable validation -
getRequired()function ensures critical variables are present - No dependencies
Usage
-
with zon: zig fetch --save "thisrepo/hash" in build.zig, add the module (the name of the module is "dotenv")
-
Create a
.envfile in your project or executable directory:# .env MY_ENV_VAR=hello ANOTHER_VAR=world -
Use dotenv to read the environment variable:
const Env = @import("dotenv"); pub fn main() !void { const alloc = std.heap.page_allocator; // read the env file var file = try std.fs.cwd().openFile(".env", .{}); defer file.close(); const content = try file.readToEndAlloc(alloc, 1024 * 1024); defer alloc.free(content); // parse the env file var env: Env = try Env.init(alloc, content); defer env.deinit(); // This will first check the .env file, then fall back to process environment if not found std.debug.print("{s}\n", .{env.get("password").?}); // Use the environment variables // ... }Alternatively, use
initWithPathfor a more convenient approach:const Env = @import("dotenv"); pub fn main() !void { const alloc = std.heap.page_allocator; // initWithPath handles file opening, reading, and cleanup automatically // Set use_process_env=true to fall back to process environment if .env file is not found var env: Env = try Env.initWithPath(alloc, ".env", 1024 * 1024, true); defer env.deinit(); // This will first check the .env file, then fall back to process environment if not found std.debug.print("{s}\n", .{env.get("password").?}); // Use the environment variables // ... } -
Use dotenv to get a key from a dotenv file at comptime:
const Env = @import("dotenv"); pub fn main() !void { const content = @embedFile(".env"); try expect(try Env.parse_key("no key", content) == null); const password = try Env.parse_key("password", content); try expect(std.mem.eql(u8, password.?, "mysecretpassword")); } -
Process environment variable support (for cloud deployments):
When a key is not found in the
.envfile,Env.get()automatically falls back to reading from the process environment. This makes it perfect for cloud deployments where environment variables are provided by the platform.Option A: Initialize without a .env file (process environment only):
const Env = @import("dotenv"); pub fn main() !void { const alloc = std.heap.page_allocator; // Initialize without a .env file - will use process environment only var env: Env = try Env.init(alloc, null); defer env.deinit(); // This will read from process environment (e.g., set by Docker, Heroku, AWS Lambda, etc.) if (env.get("DATABASE_URL")) |url| { std.debug.print("Database URL: {s}\n", .{url}); } }Option B: Use
initWithPathwith fallback (recommended for cloud deployments):const Env = @import("dotenv"); pub fn main() !void { const alloc = std.heap.page_allocator; // If .env file exists, use it; otherwise fall back to process environment // This works seamlessly in both local development and cloud deployments var env: Env = try Env.initWithPath(alloc, ".env", 1024 * 1024, true); defer env.deinit(); // This will check .env file first, then process environment if (env.get("DATABASE_URL")) |url| { std.debug.print("Database URL: {s}\n", .{url}); } }This is particularly useful for:
- Cloud platforms (Heroku, AWS Lambda, Google Cloud Run, etc.)
- Docker containers with environment variables
- CI/CD pipelines
- Production environments where .env files should not be included
- Local development where you want .env file support with cloud deployment compatibility
-
Required environment variables with
getRequired():For cases where an environment variable is mandatory, use
getRequired()which returns an error if the variable is missing:const Env = @import("dotenv"); pub fn main() !void { const alloc = std.heap.page_allocator; var env: Env = try Env.initWithPath(alloc, ".env", 1024 * 1024, true); defer env.deinit(); // getRequired() returns error.MissingRequiredEnvVar if the key is not found const database_url = try env.getRequired("DATABASE_URL"); const api_key = try env.getRequired("API_KEY"); std.debug.print("Database URL: {s}\n", .{database_url}); std.debug.print("API Key: {s}\n", .{api_key}); }This is useful for:
- Ensuring critical configuration is present before application startup
- Providing clear error messages when required variables are missing
- Avoiding null checks when you know a variable must exist
Docker Testing
The repository includes Docker support for testing process environment functionality:
docker-compose up --build
This will run all tests with environment variables set via Docker Compose, verifying that process environment variable support works correctly.
Contributing
Contributions are welcome! Fork the repository and submit a pull request.
License
dotenv-zig is licensed under the MIT License. See LICENSE for details.
Package Contents
- licenses.txt
- zigmod.lock
- LICENSE
- .dockerignore
- build.zig
- zigmod.yml
- src/root.zig
- Dockerfile
- README.md
- build.zig.zon
- docker-compose.yml
- .gitignore
History
| Published On | Tree @ Commit | Size | |
|---|---|---|---|
| v0.16 | Wed, 26 Nov 2025 09:13:38 UTC | Tree | 19.586 KB |
| v0.15 | Mon, 17 Nov 2025 19:01:32 UTC | Tree | 7.747 KB |
| v0.14 | Thu, 24 Apr 2025 21:04:26 UTC | Tree | 7.741 KB |
| v0.13 | Tue, 08 Apr 2025 15:48:05 UTC | Tree | 6.544 KB |
| v0.12 | Wed, 12 Jun 2024 15:34:02 UTC | Tree | 10.964 KB |
| v0.11 | Wed, 12 Jun 2024 15:25:43 UTC | Tree | 10.912 KB |
| v0.10 | Wed, 12 Jun 2024 15:22:48 UTC | Tree | 10.857 KB |
| v0.9 | Wed, 12 Jun 2024 15:21:54 UTC | Tree | 10.875 KB |
| v0.8 | Wed, 12 Jun 2024 14:37:08 UTC | Tree | 10.860 KB |
| v0.7 | Wed, 12 Jun 2024 14:35:42 UTC | Tree | 10.813 KB |
| v0.6 | Wed, 12 Jun 2024 14:33:30 UTC | Tree | 12.354 KB |
| v0.5 | Wed, 12 Jun 2024 14:27:44 UTC | Tree | 12.329 KB |
| v0.4 | Wed, 12 Jun 2024 14:27:32 UTC | Tree | 12.333 KB |
| v0.3 | Wed, 12 Jun 2024 14:26:47 UTC | Tree | 12.337 KB |
| v0.2 | Wed, 12 Jun 2024 09:33:53 UTC | Tree | 12.254 KB |
| v0.1 | Wed, 12 Jun 2024 09:18:57 UTC | Tree | 12.152 KB |