v6.0.0
Usage 6.0
Usage 6 is a much larger release than its version number can comfortably summarize. Since 5.1, the project has grown from a spec parser and artifact generator into a complete CLI platform: the new usage-rs reference framework for Rust, the beginnings of the usage-go reference framework, layered configuration, portable validation, richer completions, compatibility tooling, and a substantially more expressive Usage spec.
The idea is still the same: a CLI should have one machine-readable contract. In 6.0, that contract can now drive the program itself as well as its help, completions, docs, manpages, config schema, and compatibility checks.
Introducing usage-rs
usage-rs is the new reference framework for building Rust CLIs with Usage. Declare typed commands, arguments, subcommands, value enums, argument groups, and settings with ordinary structs and enums; usage-rs compiles the declaration into static data instead of constructing a command tree at startup.
That gives applications:
- Typed parsing with no runtime parser construction
- Built-in
-h,--help,help,--version, clap-shaped diagnostics, and suggestions - Generated sync/async command dispatch and
update_fromsupport - Shell completion scripts and in-process dynamic completers
- A built-in
__usage_spec__endpoint, so the running binary can describe itself - First-party assertions for parsing, help, execution, and completion behavior
On the checked-in mise-scale benchmark—211 commands, 711 flags, and 128 positionals—the parse-only path takes about 7,377 instructions / 0.7 µs, with no allocations when no owned values are bound. See the methodology and current numbers.
usage-rs is experimental: it is complete enough that usage-cli now uses it itself, but 6.x point releases may still change APIs.
Configuration becomes part of the contract
usage-rs can resolve settings across command-line, environment, and file layers while retaining provenance for every value. Its Config derive generates the registry, typed reader, and portable spec metadata from the same settings struct.
The resolver supports typed values, merge policies, aliases and renames, deprecation milestones, TOML/JSON/YAML readers, lossy reads, and explanations of where a value came from. Because config declarations live in the spec, the CLI can also generate JSON Schema and complete config keys and values.
See the configuration guide.
A substantially richer spec and CLI
The spec now covers much more of a real CLI's behavior: conflicts, requirements, overrides, groups, reusable flag sets, value-conditional rules, fixed and variadic arity, external and default subcommands, token-boundary controls, deprecations, portable expression validation, config metadata, help layout, and command effects.
Two new commands make that contract easier to operate:
usage explainshows how argv was interpreted, including token roles, fallbacks, provenance, warnings, and accumulated errors.usage diffcompares two specs and classifies changes as breaking, compatible, or metadata-only. It has machine-readable output and CI-friendly exit behavior.
Completion generation gained richer value hints, config completion, shell-safe quoting, partial-path expansion, aliases, async overlays, and --install for placing scripts where each shell expects them. JSON Schema generation for CLI config is new as well.
Introducing usage-go
usage-go is the new Go reference framework. It follows the same static-data design, generates typed command structs from a Usage spec, and keeps parsing, validation metadata, and help text linker-separable.
This work is not ready for adoption or testing yet. Its APIs and generated output are still in flux, and the published documentation is a preview of the direction rather than a stability promise.
Breaking changes and migration notes
usage-rsandusage-goshould be treated as brand-new in 6.0. Some implementation crates were accidentally published with 5.x versions, but those releases did not constitute supported public frameworks or an API lineage to migrate from. Start with the 6.0 framework documentation.UsageErris now#[non_exhaustive], and file/shell failures have dedicated variants. Downstream exhaustive matches need a fallback arm.subcommand_requiredis now enforced by the reference parser. An invocation that previously slipped through without a required child command now fails as declared.- Rust
flattendeclarations are emitted as reusableflagset/usenodes instead of duplicating flags under every command. The accepted command line is unchanged, but tools comparing serialized generated specs will see a structural change. - Usage no longer vendors or embeds bash-completion.
--include-bash-completion-liband the corresponding Rust option were removed. Generated Bash scripts require bash-completion 2.11 or newer to be installed and sourced; the scripts now diagnose a missing library clearly. - Dependency and feature cleanup removed unused transitive crates and stopped implicitly enabling capabilities for consumers. Direct
usage-libusers should declare the features they actually use.
For clap adopters, the usage-rs migration guide documents the mechanical derive mapping, known compatibility gaps, and intentional boundaries around runtime builders and ArgMatches.
Everything else
This release spans 347 commits and 500 changed files. The curated notes above are the practical overview; the full changelog retains every feature, fix, performance change, and pull request, and the complete comparison is available on GitHub.