Skip to content

--usage

Build command-line interfaces and generate their documentation

Define commands, flags, arguments, and settings using the Rust framework or a portable KDL specification. Generate shell completions, reference documentation, and client libraries from that definition.

Already have a CLI? Connect your framework →

Bash · Zsh · Fish · PowerShell · Nushell

mycli.usage.kdl
bin "mycli"
cmd "deploy" help="Deploy a service" {
    arg "<service>"
    flag "--env <env>" {
        choices "staging" "production"
    }
}

Choose how to define your CLI ​

A new Rust CLI ​

Declare commands with structs and enums. Get typed parsing, help, completion, validation, and configuration support, plus a portable spec you can export.

Start the Rust quickstart →

An existing command-line tool ​

Export a spec from clap, Cobra, or another framework, or write KDL directly. Generate reference docs and completions while keeping your application code.

Find an integration →

A script that needs an interface ​

Declare arguments and flags in comments. Usage validates the input, handles --help, and passes the parsed values to your script as environment variables.

Add parsing to a script →

Generate docs, completions, and clients ​

The specification supplies the commands, descriptions, choices, and defaults for each generator. When your interface changes, regenerate the outputs from the updated specification.

Install the Usage CLI →

Benchmarks

Parser overhead

What parsing mise use -g node@20 costs each framework, against a shadow of mise's CLI: 211 commands, 711 flags. Every program on both cards is generated from that one checked-in spec.

usage-rs vs clap, bpaf

wall time, in-process parse throughput How this is measured Each parser runs repeatedly inside one process; process startup is excluded, so these bars are not full CLI invocation times. The chart reports the fastest per-parse time from many short rounds. Minima and their ratios drift a few percent between runs and machines, hence the ~. Instructions for one cold parse, which do not drift: 4,155 · 5.89M · 21.9M, agreeing across two machines to 0.15%.

usage-rs0.19 µs
clap480 µs· ~2,500× more
bpaf1,600 µs· ~8,200× more

usage-rs starts from compiler-emitted static tables and scans only the current command's flags plus inherited globals. clap and bpaf build a parser before they can use one Where their time goes Most of clap's is constructing and validating its command tree. bpaf's is larger because it assembles a combinator tree per run as well, which reusing the parser across parses only halves. . Heap allocations for a bare parse: zero, against clap's 6,560.

usage-go vs cobra, urfave/cli, kong

wall time, in-process parse throughput How this is measured The same way as the Rust card, by a harness written to match it: each parser runs repeatedly inside one process and the fastest per-parse time from many short rounds is reported, with the collector run between rounds rather than inside them. Process startup is excluded — a Go process is about a millisecond old before main, which no parser can touch. Whole-process cost, and instructions for one parse: go/README.md.

usage-go5.9 µs
cobra110 µs· ~18× more
urfave/cli v3200 µs· ~34× more
kong3.0 ms· ~500× more

usage-go binds against package-level tables the linker laid out before main. cobra and urfave build a command tree per process and kong reflects over a struct, none of which a spec-driven parser has to do. Instructions for the same parse: 123k vs cobra's 2.8M, urfave/cli's 5.8M, kong's 66.7M — and 1,955 for the binder under usage-go's typed front door.

Methodology and raw numbers: go/README.md · tasks/perf-shadow.sh · time-sweep.rs

MIT LicenseCopyright © 2026jdx.dev