urfave/cli

A declarative, dependency-free Go package for building fast, friendly command-line tools.

Framework
Go
vv1.22.17
24,216stars
MIT License

Repository Health

Pre-computed score based on development activity, maintenance, community, maturity, and trend momentum.How we score it →
92/100Excellent
Development Activity96
Maintenance96
Community76
Maturity60
Momentum40

Technical Analysis

AI-assessed by reading the actual repository — architecture, code quality, innovation, and documentation.How we score it →
88/100Excellent
Architecture85
Code Quality90
Innovation80
Learning Curve95

urfave/cli is a declarative Go package for building command-line applications, offering commands, subcommands, and flags defined directly as Go structs rather than through builder chains or code generation. It ships with zero dependencies outside the Go standard library and covers most of what a CLI tool needs out of the box: alias- and prefix-matched subcommands, typed flags for simple types, slices, durations, and timestamps, compound short-flag parsing, and a permissive help system with typo suggestions.

Originally created for Docker’s CLI and now maintained by a volunteer team, the project has matured through three major versions (v1 through v3) while keeping the same declarative philosophy. Companion modules (urfave/cli-altsrc for config-file input, urfave/cli-docs for man/Markdown generation) let teams add functionality without bloating the core package, and built-in shell-completion generation covers bash, zsh, fish, and PowerShell.

What You Get

  • Declarative Command and Flag structs — describe a CLI as data instead of chaining builder calls
  • Nested subcommands with alias and prefix matching
  • Typed flags for strings, numbers, bools, durations, and timestamps, plus slice variants of each, via a generic FlagBase implementation
  • Automatic, permissive help text generation with “did you mean” suggestions for mistyped commands and flags
  • Built-in shell completion generation for bash, zsh, fish, and PowerShell
  • Zero runtime dependencies outside the Go standard library

Common Use Cases

  • Building an internal developer CLI with multiple subcommands and shared flags
  • Wrapping an API or service behind a friendly command-line client
  • Adding config-file, environment-variable, or plain-text-file input sources via the urfave/cli-altsrc module
  • Generating man pages and Markdown docs for a CLI via the urfave/cli-docs module

Under The Hood

Architecture A Command struct is both the application root and every node beneath it — the same type carries flags, an Action, lifecycle hooks, and a slice of child Commands, so parsing is naturally recursive: command_setup.go prepares a command’s flags and defaults, command_parse.go walks argv against the active flag set, and command_run.go dispatches through the ArgValidator/Before/Action/After sequence before descending into a matched subcommand. Help and shell completion (help.go, completion.go, template.go) sit alongside this tree and read the same Command/Flag metadata, so no separate registration step is needed to keep help text or completions in sync with the actual command definitions.

Tech Stack The library targets Go 1.22+ and depends on nothing beyond the standard library at runtime; its only declared dependency, stretchr/testify (plus an indirect YAML parser it pulls in), is used solely by the test suite. Generics do the heavy lifting for flags: flag_impl.go defines a single FlagBase[T, C, VC] type that the concrete String, Int, Bool, Duration, Timestamp, and slice-of-each flags are generated from, avoiding hand-duplicated parsing logic per type. The project’s documentation site (docs/, built with mkdocs) is published via a dedicated GitHub Actions workflow, separate from the Go module itself.

Code Quality The repository carries an extensive suite of table-driven tests across roughly two dozen _test.go files covering flags, commands, help output, shell completion, and error paths, using testify for assertions. A staticcheck configuration and dedicated lint and test GitHub Actions workflows run on every change, and errors are handled as explicit typed values (errors.go defines a composite error type for aggregating multiple failures) rather than silently swallowed.

What Makes It Unique Where many Go CLI libraries push users toward imperative builder APIs or external code generation, urfave/cli stays purely declarative — the whole application is describable as literal struct values. Its generic flag implementation gives type-safe custom flag types without codegen, its help system proactively suggests corrections for typos instead of just failing, and it deliberately keeps the core package dependency-free while offloading optional concerns (structured config sources, doc generation) to separate companion modules maintained under the same organization.

Join founders buildingwith open source

Opinionated takes, migration guides, cost-saving tips, and insights from the open source ecosystem.

Subscribe on Substack
Join 750+ subscribers

Search