# Argzon: Command-line argument parsing library using ZON

**URL:** <https://ziggit.dev/t/argzon-command-line-argument-parsing-library-using-zon/8941>\
**Category:** Showcase\
**Tags:** zon, cli\
**Created:** [March 8, 2025, 1:22pm UTC](https://ziggit.dev/t/argzon-command-line-argument-parsing-library-using-zon/8941 "2025-03-08T13:22:30Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![tensorush](https://ziggit.dev/letter_avatar_proxy/v4/letter/t/6a8cbe/32.png) [@tensorush](https://ziggit.dev/u/tensorush)\
**Post date:** [March 8, 2025, 1:22pm UTC](https://ziggit.dev/t/argzon-command-line-argument-parsing-library-using-zon/8941/1 "2025-03-08T13:22:30Z")

</div>

It might seem like yet another CLI argument parsing library in Zig, but this one comes with a twist – it works based on a ZON struct of your CLI definition. And the inspiration behind it is @MasonRemaley’s amazing work on the compiler’s ZON implementation as well as [`structopt`](https://github.com/Games-by-Mason/structopt).

Long story short, I’ve [rewritten `structopt` to support ZON-like structs](https://github.com/Games-by-Mason/structopt/issues/11). No fancy parsing, but pretty nice to use (will be even nicer once we’re able to [import ZON files without result types](https://github.com/ziglang/zig/pull/22907)).

See the [example’s code](https://codeberg.org/tensorush/argzon/src/branch/main/example/main.zig) and [build step](https://codeberg.org/tensorush/argzon/src/branch/main/build.zig#L41-L63) in the repo:

> **[argzon](https://codeberg.org/tensorush/argzon)**
>
> Command-line argument parsing library using ZON.

Also, here’s how [`zq`](https://ziggit.dev/t/zq-command-line-zon-processor/8722) uses it:

> **[zq/src/main.zig at main](https://codeberg.org/tensorush/zq/src/branch/main/src/main.zig)**
>
> zq - Command-line ZON processor.

---

<div class="post-metadata">

**Author:** ![MasonRemaley](https://ziggit.dev/user_avatar/ziggit.dev/masonremaley/32/4454_2.png) [@MasonRemaley](https://ziggit.dev/u/MasonRemaley)\
**Post date:** [March 9, 2025, 7:32am UTC](https://ziggit.dev/t/argzon-command-line-argument-parsing-library-using-zon/8941/2 "2025-03-09T07:32:53Z")

</div>

Nice, I’m looking forward to checking this out when I have a chance!

---

<div class="post-metadata">

**Author:** ![tensorush](https://ziggit.dev/letter_avatar_proxy/v4/letter/t/6a8cbe/32.png) [@tensorush](https://ziggit.dev/u/tensorush)\
**Post date:** [April 3, 2025, 10:06pm UTC](https://ziggit.dev/t/argzon-command-line-argument-parsing-library-using-zon/8941/3 "2025-04-03T22:06:09Z")

</div>

I’ve added `excludes` for named arguments to indicate that they cannot be specified together.

See how [`zq`](https://ziggit.dev/t/zq-command-line-zon-processor/8722) uses it:

- [zq/src/main.zig at main - tensorush/zq - Codeberg.org](https://codeberg.org/tensorush/zq/src/branch/main/src/main.zig#L28-L31)

- [zq/src/main.zig at main - tensorush/zq - Codeberg.org](https://codeberg.org/tensorush/zq/src/branch/main/src/main.zig#L51-L54)

---

<div class="post-metadata">

**Author:** ![tensorush](https://ziggit.dev/letter_avatar_proxy/v4/letter/t/6a8cbe/32.png) [@tensorush](https://ziggit.dev/u/tensorush)\
**Post date:** [April 25, 2025, 10:44am UTC](https://ziggit.dev/t/argzon-command-line-argument-parsing-library-using-zon/8941/4 "2025-04-25T10:44:13Z")

</div>

## 1) Dependencies feature

Added `dependencies` feature for named arguments to depend on each other. Basically, the opposite of `excludes`, although `dependencies` are declared one-way, whereas `excludes` are mutually exclusive (two-way).

## 2) Enum option values for dependencies and excludes

Now you can declare a dependency on or an exclude of specific enum option values, like this: `"option value1 value2"`.

## 3) Zig CLI example

Started [porting Zig CLI](https://codeberg.org/tensorush/argzon/src/branch/main/examples/zig/main.zig) to see how feature-complete `argzon` is.

Still WIP, but here’s a close comparison (minor edits aside) for `zig fetch` subcommand’s help output showcasing the new `dependencies` feature.

### Original

```zig
Usage: zig fetch [options] <url>
Usage: zig fetch [options] <path>

    Copy a package into the global cache and print its hash.
    <url> must point to one of the following:
      - A git+http / git+https server for the package
      - A tarball file (with or without compression) containing
        package source
      - A git bundle file containing package source

Examples:

  zig fetch --save git+https://example.com/andrewrk/fun-example-tool.git
  zig fetch --save https://example.com/andrewrk/fun-example-tool/archive/refs/heads/master.tar.gz

Options:
  -h, --help Print this help and exit
  --global-cache-dir [path] Override path to global Zig cache directory
  --debug-hash Print verbose hash information to stdout
  --save Add the fetched package to build.zig.zon
  --save=[name] Add the fetched package to build.zig.zon as name
  --save-exact Add the fetched package to build.zig.zon, storing the URL verbatim
  --save-exact=[name] Add the fetched package to build.zig.zon as name, storing the URL verbatim

```

### `argzon`

#### Usage snippet

```zig
├── fetch [-n <string>] [-G <string>] [-s] [-x] [-H] <string>

```

#### Help snippet

```zig
fetch Copy package into global cache and print its hash.
  Examples:
    zig fetch --save git+https://example.com/user/repo.git
    zig fetch --save https://example.com/user/repo/archive/refs/heads/main.tar.gz

  Options:
    -n, --save-name <string> Add fetched package to build.zig.zon with name.
    -G, --global-cache-dir <string> Override path to global cache directory.

  Flags:
    -s, --save Add fetched package to build.zig.zon.
    -x, --exact Store URL verbatim.
      Dependencies:
        --save
        --save-name
    -H, --hash Print verbose hash information for debugging.

  Positionals:
    URL_OR_PATH <string> URL or local directory path.
      URL must point to one of the following:
        - Git bundle file containing package source
        - Git HTTP package server (git+http / git+https)
        - Tarball file (with or without compression) containing package source

```

P.S. I’ve discovered that `zig detect-cpu` works in release builds even though it’s listed in `zig -h` output among debug subcommands, which you won’t see unless you’re using a debug build of the compiler.

---

<div class="post-metadata">

**Author:** ![tensorush](https://ziggit.dev/letter_avatar_proxy/v4/letter/t/6a8cbe/32.png) [@tensorush](https://ziggit.dev/u/tensorush)\
**Post date:** [August 24, 2025, 5:58pm UTC](https://ziggit.dev/t/argzon-command-line-argument-parsing-library-using-zon/8941/5 "2025-08-24T17:58:09Z")

</div>

Updated to Zig 0.15.1.  
Now you can just import a ZON file with your CLI definition – it’s kinda neat:

> **[argzon](https://codeberg.org/tensorush/argzon/src/branch/main/examples/basic/)**
>
> Command-line argument parsing library using ZON.

Btw, glad to see a [minimal CLI parser likely landing in the next Zig release](https://github.com/ziglang/zig/pull/24881)!

---

<div class="post-metadata">

**Author:** ![ion232](https://ziggit.dev/user_avatar/ziggit.dev/ion232/32/5791_2.png) [@ion232](https://ziggit.dev/u/ion232)\
**Post date:** [August 25, 2025, 9:00am UTC](https://ziggit.dev/t/argzon-command-line-argument-parsing-library-using-zon/8941/6 "2025-08-25T09:00:36Z")

</div>

This looks great, I’ve always been looking for something like this. The separation of data and implementation makes it so much clearer.
