{"id":48156913,"url":"https://github.com/ataias/zap","last_synced_at":"2026-04-04T17:18:46.232Z","repository":{"id":343089865,"uuid":"1176179114","full_name":"ataias/zap","owner":"ataias","description":"Zig Argument Parser","archived":false,"fork":false,"pushed_at":"2026-03-08T23:47:04.000Z","size":23,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-03-09T00:21:54.556Z","etag":null,"topics":["zig","zig-library"],"latest_commit_sha":null,"homepage":"","language":"Zig","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/ataias.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-03-08T18:14:00.000Z","updated_at":"2026-03-08T23:47:05.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/ataias/zap","commit_stats":null,"previous_names":["ataias/zap"],"tags_count":null,"template":false,"template_full_name":null,"purl":"pkg:github/ataias/zap","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ataias%2Fzap","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ataias%2Fzap/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ataias%2Fzap/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ataias%2Fzap/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ataias","download_url":"https://codeload.github.com/ataias/zap/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ataias%2Fzap/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31407644,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-04T10:20:44.708Z","status":"ssl_error","status_checked_at":"2026-04-04T10:20:06.846Z","response_time":60,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["zig","zig-library"],"created_at":"2026-04-04T17:18:45.437Z","updated_at":"2026-04-04T17:18:46.199Z","avatar_url":"https://github.com/ataias.png","language":"Zig","funding_links":[],"categories":[],"sub_categories":[],"readme":"# zap\n\n\u003e **Work in progress** -- the API is not yet stable and may change.\n\nA CLI argument parsing library for Zig that uses compile-time reflection to turn\nstruct definitions into fully featured command-line interfaces. No macros, no\ncode generation, no runtime overhead -- just define a struct and `zap.run` it.\n\nZero dependencies beyond the Zig standard library.\n\n## Quick start\n\n```zig\nconst std = @import(\"std\");\nconst zap = @import(\"zap\");\n\nconst Add = struct {\n    pub const meta: zap.CommandMeta = .{\n        .description = \"Add numbers and print the result\",\n    };\n\n    verbose: bool = false,\n    values: []const i64,\n\n    pub fn run(self: @This(), init: std.process.Init) !void {\n        var sum: i64 = 0;\n        for (self.values) |v| sum += v;\n\n        var buf: [4096]u8 = undefined;\n        var writer = std.Io.File.stdout().writer(init.io, \u0026buf);\n        if (self.verbose) {\n            for (self.values, 0..) |v, i| {\n                if (i \u003e 0) try writer.interface.writeAll(\" + \");\n                try writer.interface.print(\"{d}\", .{v});\n            }\n            try writer.interface.print(\" = {d}\\n\", .{sum});\n        } else {\n            try writer.interface.print(\"{d}\\n\", .{sum});\n        }\n        try writer.interface.flush();\n    }\n};\n\npub fn main(init: std.process.Init) !void {\n    return zap.run(Add, init);\n}\n```\n\n```\n$ add 1 2 3\n6\n\n$ add --verbose 1 2 3\n1 + 2 + 3 = 6\n\n$ add --help\nUSAGE: add [options] \u003cvalues\u003e...\n\nAdd numbers and print the result\n\nARGUMENTS:\n  \u003cvalues\u003e...\n\nOPTIONS:\n  -v, --verbose         (default: false)\n  -h, --help             Show help information\n```\n\n## Installation\n\nRequires Zig `master` (minimum `0.16.0-dev.2261+d6b3dd25a`).\n\nAdd zap as a dependency in your `build.zig.zon`:\n\n```\nzig fetch --save git+https://github.com/ataias/zap\n```\n\nThen in your `build.zig`:\n\n```zig\nconst zap_dep = b.dependency(\"zap\", .{\n    .target = target,\n    .optimize = optimize,\n});\n\nexe.root_module.addImport(\"zap\", zap_dep.module(\"zap\"));\n```\n\n## How it works\n\nStruct fields map directly to CLI arguments:\n\n| Field type | CLI form | Example |\n|---|---|---|\n| `bool` | Flag | `--verbose`, `-v` |\n| `u8` (default 0) | Counted flag | `-vvv` sets to 3 |\n| Integer/Float | Option | `--port 3000` |\n| `enum` | Option | `--color red` |\n| `[]const u8` | String option | `--name alice` |\n| `Positional(T)` | Positional | `\u003cfile\u003e` |\n| `[]const T` | Multi positional | `\u003cvalues\u003e...` |\n| `?T` | Optional argument | omitting is valid |\n\nFields with default values become optional. Fields without defaults are required.\n\n### Naming conventions\n\n- Struct field names use `snake_case`; zap converts them to `--kebab-case` on the CLI (`hex_output` becomes `--hex-output`)\n- Short flags (`-v`, `-f`, etc.) are assigned automatically from the first character of each field name, with collisions resolved at compile time\n- Struct names use `CamelCase`; subcommand names are derived as `kebab-case` (`HexOutput` becomes `hex-output`)\n\n## Subcommands\n\nDefine subcommands by listing them in `meta.subcommands`:\n\n```zig\nconst Add = struct {\n    pub const meta: zap.CommandMeta = .{ .description = \"Add numbers\" };\n    values: []const i64,\n    pub fn run(self: @This(), init: std.process.Init) !void { ... }\n};\n\nconst Multiply = struct {\n    pub const meta: zap.CommandMeta = .{ .description = \"Multiply numbers\" };\n    values: []const i64,\n    pub fn run(self: @This(), init: std.process.Init) !void { ... }\n};\n\nconst Math = struct {\n    pub const meta: zap.CommandMeta = .{\n        .description = \"A math utility\",\n        .subcommands = \u0026.{ Add, Multiply },\n    };\n};\n\npub fn main(init: std.process.Init) !void {\n    return zap.run(Math, init);\n}\n```\n\n```\n$ math add 2 3\n5\n\n$ math multiply 2 3 4\n24\n\n$ math --help\nUSAGE: math \u003csubcommand\u003e\n\nA math utility\n\nSUBCOMMANDS:\n  add                    Add numbers\n  multiply               Multiply numbers\n\nOPTIONS:\n  -h, --help             Show help information\n```\n\n## Field descriptions\n\nProvide per-field descriptions via `meta.field_descriptions`:\n\n```zig\nconst Cp = struct {\n    pub const meta = .{\n        .description = \"Copy files\",\n        .field_descriptions = .{\n            .output = \"Destination path\",\n            .force = \"Overwrite without prompting\",\n        },\n    };\n\n    output: []const u8,\n    force: bool = false,\n};\n```\n\n```\nUSAGE: cp [options]\n\nCopy files\n\nOPTIONS:\n  -o, --output          Destination path\n  -f, --force           Overwrite without prompting (default: false)\n  -h, --help             Show help information\n```\n\n## Shell completions\n\nZap generates shell completion scripts for fish, zsh, and bash. Every command\nbuilt with `zap.run` automatically supports `--generate-completion-script`:\n\n```\n$ myapp --generate-completion-script fish | source  # fish\n$ myapp --generate-completion-script zsh  \u003e_myapp \u0026\u0026 source _myapp  # zsh\n$ eval \"$(myapp --generate-completion-script bash)\"  # bash\n```\n\nFine-tune what the shell suggests by adding `field_completions` to your command\nmetadata:\n\n```zig\npub const meta = .{\n    .field_completions = .{\n        .target = .{ .values = \u0026.{ \"prod\", \"staging\", \"dev\" } },\n        .config = .{ .file_path_with_extensions = \u0026.{ \"json\", \"yaml\" } },\n        .service = .{ .from_command = \"echo web api worker\" },\n    },\n};\n```\n\nAvailable completion hints:\n\n| Hint | Completes with |\n|---|---|\n| `.file_path` | File paths |\n| `.file_path_with_extensions` | Files matching given extensions |\n| `.dir_path` | Directory paths |\n| `.executable` | Executable commands |\n| `.values` | A fixed set of strings |\n| `.from_command` | Output of a shell command |\n\nEnum fields automatically complete with their variant names.\n\n## Hidden fields and subcommands\n\nFields and subcommands can be hidden from help output while still being\nfunctional:\n\n```zig\npub const meta: zap.CommandMeta = .{\n    .hidden_fields = \u0026.{\"debug_trace\"},\n    .hidden_subcommands = \u0026.{\"debug-info\"},\n    .subcommands = \u0026.{ Deploy, Status, DebugInfo },\n};\n```\n\nHidden items are omitted from `--help` and completion scripts but are still\naccepted when used directly.\n\n## Error handling\n\nZap produces clear error messages and suggests corrections for typos using\nLevenshtein distance:\n\n```\n$ add --badopt\nerror: unknown option '--badopt'\nUsage: add [options] \u003cvalues\u003e...\n\n$ add --verbos\nerror: unknown option '--verbos', did you mean '--verbose'?\n\n$ math ad\nerror: unknown subcommand 'ad', did you mean 'add'?\n```\n\n## Building and testing\n\n```sh\n# Run all tests (unit + integration)\nzig build test\n\n# Run with a specific optimization level\nzig build test -Doptimize=ReleaseSafe\n\n# Build the examples\nzig build\n```\n\n## Cross-compilation\n\nZap is tested against the following targets in CI:\n\n- `aarch64-linux`\n- `x86_64-macos`, `aarch64-macos`\n- `x86_64-windows`\n- `x86_64-freebsd`, `aarch64-freebsd`\n\n## License\n\nMIT\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fataias%2Fzap","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fataias%2Fzap","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fataias%2Fzap/lists"}