A modern, minimal argument parser for Zig.
argh is a simple, flexible argument parser for Zig projects. It supports:
- Long and short flags/options (e.g.
--help,-h) - Short options for all option types (e.g.
-n 5for--number 5) - Positional arguments with min/max count
- Required arguments
- Mutually exclusive groups
- Helpful error and help messages
- Configurable help formatting (flat/simple/complex grouping; defaults to flat)
- Grouped help output (see
printHelpWithOptions(.simple_grouped)) - Type-safe int/float/bool options with min/max constraints
- Memory-safe: all allocations are freed, no leaks
- Fully documented API with Zig doc comments
const argh = @import("argh");
const std = @import("std");
pub fn main() !void {
var arena = std.heap.ArenaAllocator.init(std.heap.page_allocator);
defer arena.deinit();
const allocator = arena.allocator();
const args = try std.process.argsAlloc(allocator);
defer std.process.argsFree(allocator, args);
var parser = argh.Parser.init(allocator, args);
try parser.addFlag("-h", "--help", "Show help message");
try parser.addOption("--name", "-n", "world", "Name to greet");
try parser.addIntOption("--count", "-c", 1, "How many times", 1, 10);
try parser.addOption("--loud", "-L", "false", "Loud greeting");
parser.options.getPtr("--loud").?.typ = .bool;
try parser.parse();
if (parser.flagPresent("--help")) {
parser.printHelpWithOptions(.simple_grouped);
return;
}
const name = parser.getOption("--name") orelse "world";
const count = try parser.getOptionInt("--count") orelse 1;
const loud = try parser.getOptionBool("--loud") orelse false;
for (0..count) |_| {
if (loud) {
std.debug.print("HELLO, {s}!\n", .{name});
} else {
std.debug.print("Hello, {s}.\n", .{name});
}
}
}This example demonstrates:
- Short and long options for all types
- Type-safe int and bool option access
- Grouped help output
- Memory safety via arena allocator
Curious about what's next? See planned and potential features in the Roadmap.
- Simple, declarative API
- Long and short flags/options (e.g.
--help,-h) - Type-safe int/float options with min/max constraints
- Positional arguments with min/max count constraints
- Required arguments
- Mutually exclusive groups
- Helpful error and help messages
- Configurable help output style (see
HelpStyle) - Fully documented API (Zig doc comments)
Install with Zig's package manager:
zig fetch --save git+https://github.com/dayvster/arghThen add to your build.zig:
const argh_pkg = b.dependency("argh", .{
.target = target,
.optimize = optimize,
});
// const exe = b.addExecutable(...); ...
// make sure to place this after creating your executable
exe.root_module.addImport("argh", argh_pkg.module("argh"));const std = @import("std");
const argparse = @import("argh");
pub fn main() !void {
var arena = std.heap.ArenaAllocator.init(std.heap.page_allocator);
defer arena.deinit();
const allocator = arena.allocator();
const args = try std.process.argsAlloc(allocator);
defer std.process.argsFree(allocator, args);
var parser = argparse.Parser.init(allocator, args);
try parser.addFlag("-h", "--help", "Show help message");
try parser.addOptionWithShort("--name", "-n", "World", "Name to greet");
try parser.addPositionalWithCount("input", "Input files", 1, 2); // min/max count
try parser.parse();
if (parser.errors.items.len > 0) {
parser.printErrors();
parser.printHelp(); // prints help in flat style by default
return;
}
if (parser.flagPresent("-h") or parser.flagPresent("--help")) {
parser.printHelp(); // prints help in flat style by default
return;
}
const name = parser.getOption("--name") orelse "World";
std.debug.print("Hello, {s}!\n", .{ name });
for (parser.positionals.items) |pos| {
if (pos.value) |val| std.debug.print("Input: {s}\n", .{val});
}
}const std = @import("std");
const argparse = @import("argh");
pub fn main() !void {
var arena = std.heap.ArenaAllocator.init(std.heap.page_allocator);
defer arena.deinit();
const allocator = arena.allocator();
const args = try std.process.argsAlloc(allocator);
defer std.process.argsFree(allocator, args);
var parser = argparse.Parser.init(allocator, args);
try parser.addIntOption("--count", 5, "How many times", 1, 10);
try parser.addFloatOption("--ratio", 0.5, "A ratio", 0.0, 1.0);
try parser.parse();
if (parser.errors.items.len > 0) {
parser.printErrors();
parser.printHelp(); // prints help in flat style by default
return;
}
const count = try parser.getOptionInt("--count") orelse 5;
const ratio = try parser.getOptionFloat("--ratio") orelse 0.5;
std.debug.print("count: {d}\n", .{count});
std.debug.print("ratio: {:.2}\n", .{ratio});
}- Flags:
try parser.addFlag("-h", "--help", "Show help message");
- Options:
try parser.addOptionWithShort("--name", "-n", "World", "Name to greet");
- Positional Arguments:
try parser.addPositional("input", "Input file", true, null);
- Required Arguments:
try parser.setRequired("--name");
- Mutually Exclusive Groups:
try parser.addMutexGroup("group1", &[_][]const u8{ "--foo", "--bar" });
By default, parser.printHelp() prints help in the flat style.
To use a different style, use printHelpWithOptions:
parser.printHelpWithOptions(argparse.Parser.HelpStyle.simple_grouped);
parser.printHelpWithOptions(argparse.Parser.HelpStyle.complex_grouped);- Short and long flags/options
- Required and default values
- Mutually exclusive argument groups
- Automatic help and error output
- Simple, no-macro API
- Minimal: No macros, no codegen, no dependencies.
- Clear: Easy to read, easy to debug.
- Flexible: Supports most CLI patterns out of the box.
- Modern: Designed for Zig 0.15+.
Pull requests and issues are welcome! Please keep code and documentation clear and minimal.
MIT