# Another CLI Library

**URL:** <https://ziggit.dev/t/another-cli-library/18134>\
**Category:** Showcase\
**Created:** [October 29, 2026, 7:07am UTC](https://ziggit.dev/t/another-cli-library/18134 "2026-10-29T07:07:23Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![jeffective](https://ziggit.dev/user_avatar/ziggit.dev/jeffective/32/3116_2.png) [@jeffective](https://ziggit.dev/u/jeffective)\
**Post date:** [October 29, 2026, 7:07am UTC](https://ziggit.dev/t/another-cli-library/18134/1 "2026-10-29T07:07:23Z")

</div>

Project link: [https://codeberg.org/jeffective/cli](https://codeberg.org/jeffective/cli)

Hello everyone, I’ve repackaged my [std.cli attempt](https://codeberg.org/ziglang/zig/pulls/31620) (command line argument parser) as a module. The ethos behind the design is explained in detail in the PR, but the short version is that it is an attempt at being the opposite of “type-driven” while retaining the same direct access to parsed fields. This means the parse function can be understood first from the types of its arguments, instead of its docs.

So the following cli definition:

```zig
pub const command: cli.Command = .{
    .name = .cowsay,
    .positional_args = &.{
        .init(.message, [:0]const u8, .{ .help = "Message said by the cow." }),
    },
    .named_args = &.{
        .init(.red, bool, .{ .help = "Change text color to red.", .default_value = false }),
    },
    .help = "Make a cow speak.\n",
};

```

can use the parse result like this:

```zig
const parsed = try cli.parse(
    command,
    try init.minimal.args.toSlice(init.arena.allocator()),
    .{
        .exit_usage_error = true,
        .render_usage_errors = true,
        .exit_help = true,
        .render_help = .{ .generated = io },
    },
);

...

if (parsed.kind.args.red) {
    try out.writeAll("\x1b[31m");
}
...

try out.print("{s}", .{parsed.kind.args.message});

```

Unfortunately there is a lot of comptime in there, so ZLS won’t be able to provide autocomplete until the compiler server comes, but I really like working directly with the types like this, already parsed for me (like std.json).

### Supported Zig versions

- 0.17.0
- 0.16.0

---

<div class="post-metadata">

**Author:** ![zmitchell](https://ziggit.dev/user_avatar/ziggit.dev/zmitchell/32/5377_2.png) [@zmitchell](https://ziggit.dev/u/zmitchell)\
**Post date:** [October 29, 2026, 10:49pm UTC](https://ziggit.dev/t/another-cli-library/18134/2 "2026-10-29T22:49:38Z")

</div>

Codeberg is down at the moment (sigh) so pardon me if this is answered in the linked PR, but does “attempt” mean that the effort ultimately was rejected, that it’s in discussion, etc?

---

<div class="post-metadata">

**Author:** ![alanza](https://ziggit.dev/user_avatar/ziggit.dev/alanza/32/6006_2.png) [@alanza](https://ziggit.dev/u/alanza)\
**Post date:** [October 29, 2026, 11:07pm UTC](https://ziggit.dev/t/another-cli-library/18134/3 "2026-10-29T23:07:22Z")

</div>

iirc, I think the accepted proposal now includes a spec for a more “type-driven” design ?

---

<div class="post-metadata">

**Author:** ![jeffective](https://ziggit.dev/user_avatar/ziggit.dev/jeffective/32/3116_2.png) [@jeffective](https://ziggit.dev/u/jeffective)\
**Post date:** [October 30, 2026, 12:32am UTC](https://ziggit.dev/t/another-cli-library/18134/4 "2026-10-30T00:32:18Z")

</div>

Yes, core team ultimately decided to stay with type-driven. There were many designs proposed with real implementations to back them up, you should take a look! Lots of interesting ways people approached it.

---

<div class="post-metadata">

**Author:** ![pierrelgol](https://ziggit.dev/user_avatar/ziggit.dev/pierrelgol/32/10233_2.png) [@pierrelgol](https://ziggit.dev/u/pierrelgol)\
**Post date:** [October 30, 2026, 9:27pm UTC](https://ziggit.dev/t/another-cli-library/18134/5 "2026-10-30T21:27:58Z")

</div>

yours was my favorite, I really liked the API so I’m glad you saved it as a library 🙂

---

<div class="post-metadata">

**Author:** ![Salmon](https://ziggit.dev/user_avatar/ziggit.dev/salmon/32/10236_2.png) [@Salmon](https://ziggit.dev/u/Salmon)\
**Post date:** [October 30, 2026, 9:39pm UTC](https://ziggit.dev/t/another-cli-library/18134/6 "2026-10-30T21:39:04Z")

</div>

Nice work. I followed the cli discussion with interest, and I wonder if anyone is working on the accepted proposal. I will try out yours in the weekend.

---

<div class="post-metadata">

**Author:** ![nilsj](https://ziggit.dev/user_avatar/ziggit.dev/nilsj/32/9379_2.png) [@nilsj](https://ziggit.dev/u/nilsj)\
**Post date:** [November 1, 2026, 9:20pm UTC](https://ziggit.dev/t/another-cli-library/18134/7 "2026-11-01T21:20:59Z")

</div>

I was actually looking for a CLI library earlier and thought back to your PR which (to me) was superior to the API provided by the existing libraries I found, so started using this 🎉
