Typed command-line applications for Go: flags, arguments, subcommands, environment values, automatic help, shell completion, and invocation-owned resources.
Go 1.27.0+ is required.
go get github.com/echocat/cli4gpackage main
import (
"context"
"fmt"
"os"
cli "github.com/echocat/cli4g"
)
type options struct {
Name string `argument:"name" required:"true"`
Greeting string `flag:"greeting" short:"g" default:"Hello"`
}
func main() {
cli.NewApplication[options]("greet", "Greet someone.").
WithHandler(greet).
MustCreateParseAndExecute(context.Background(), nil, os.Args[1:]...)
}
func greet(_ context.Context, opts options) error {
_, err := fmt.Printf("%s, %s!\n", opts.Greeting, opts.Name)
return err
}greet Ada # Hello, Ada!
greet -g Hey Ada # Hey, Ada!
greet --helpThe default error handler exits with 2 for input errors, 130 for cancellation, or 1 for other failures. For embedding, disable it with WithErrorHandlerEnabled(false).
- Typed options: struct tags define inputs; handlers receive typed values.
- Ordered lifecycle: parsing resolves and validates all selected options before initialization; handlers follow successful initialization.
- Owned resources and cleanup:
ParseAndExecutecloses invocation-owned resources from child to parent, on success and returned errors—including partial initialization failures. - Reusable definitions: compile once, then parse independent invocations repeatedly or concurrently.
- Profiles: select compatible flag, argument, and command variants for each parse.
- Consistent inputs: explicit CLI/environment/default precedence and validation rules.
- Extensible values: custom codecs support application-specific types and resources.
- Efficient reuse: competitive runtime and allocation costs in the measured workloads.
Qualitative ratings for the compared versions: ★★★ strong · ★★☆ moderate/partial · ★☆☆ limited · — no native support.
| Capability | cli4g | urfave/cli | Cobra | Kong | Go flag |
|---|---|---|---|---|---|
| Struct-tag option binding | ★★★ | — | — | ★★★ | — |
| Definition simplicity (measured adapters)1 | ★★★ | ★★★ | ★☆☆ | ★★★ | ★☆☆ |
| Command trees and automatic help | ★★★ | ★★★ | ★★★ | ★★★ | — |
| Custom value types | ★★★ | ★★★ | ★★★ | ★★★ | ★★★ |
| Lifecycle and resource cleanup | ★★★ | ★★☆ | ★★☆ | ★★☆ | — |
| Compile once, isolated concurrent parses | ★★★ | — | — | — | — |
| Per-parse schema profiles | ★★★ | — | — | — | — |
| Shell completion | ★★★ | ★★★ | ★★★ | — | — |
| Setup/compile + first invocation speed2 | ★★☆ | ★★☆ | ★★★ | ★☆☆ | ★★★ |
| Parse/execute speed on reuse2 | ★★★ | ★★☆ | ★★★ | ★☆☆ | ★★★ |
Isolated parses keep each invocation's values independent. Resource cleanup includes rollback after partial initialization failures; hooks alone need application-managed ownership.
See benchmarks and methodology for timings, allocations, code size, and cognitive complexity.
- Struct-tag/Annotations reference
- Profiles and schema variants
- CLI API and usage
- Codecs and custom values
- CLI benchmark results
- Runnable examples —
mise example <name> [arguments...] - Development · Releasing
Footnotes
-
Based on the benchmark adapters' cognitive complexity; lower is better: cli4g 1, urfave/cli 0, Cobra 14, Kong 3, Go
flag11–14. Includes handlers, reuse/reset, cleanup, and required helper methods; measures control flow rather than overall API ergonomics. ↩ -
Based on the measured root/subcommand workloads. Setup is
OneShot: definition creation/compilation plus one parse/execute and cleanup. Reuse isReuse/100andReuse/10000, including amortized setup and cleanup. Native binding modes differ; Goflagis a minimal baseline with application-written command dispatch. ↩ ↩2