Introduction
Cobra is the standard library for building CLI applications in Go. If you have used kubectl, docker, gh (GitHub CLI), hugo, or helm — you have used Cobra. It provides a clean structure for commands, subcommands, flags, and arguments with automatic help generation, shell completions, and man page generation.
With over 44,000 GitHub stars, Cobra powers the CLI of virtually every major Go project. Its companion library Viper handles configuration, making the Cobra+Viper combination the go-to stack for Go CLI development.
What Cobra Does
Cobra organizes CLI applications into commands (like git commit, docker run). Each command can have subcommands, persistent and local flags, positional arguments with validation, and pre/post-run hooks. It generates help text, usage strings, and shell completion scripts automatically.
Architecture Overview
[CLI Application]
mycli serve --port 8080 --verbose
|
[Cobra Command Tree]
rootCmd
+-- serveCmd (with --port flag)
+-- configCmd
| +-- config setCmd
| +-- config getCmd
+-- versionCmd
|
[Flag Parsing]
pflag library (POSIX-compatible)
Persistent flags (inherited)
Local flags (command-specific)
|
[Auto-Generated]
--help, --version
Shell completions
Man pagesSelf-Hosting & Configuration
// cmd/root.go
package cmd
import (
"fmt"
"os"
"github.com/spf13/cobra"
"github.com/spf13/viper"
)
var cfgFile string
var verbose bool
var rootCmd = &cobra.Command{
Use: "mycli",
Short: "A brief description of your application",
Long: "A longer description that spans multiple lines.",
}
func init() {
rootCmd.PersistentFlags().StringVar(&cfgFile, "config", "", "config file")
rootCmd.PersistentFlags().BoolVarP(&verbose, "verbose", "v", false, "verbose output")
}
func Execute() {
if err := rootCmd.Execute(); err != nil {
fmt.Fprintln(os.Stderr, err)
os.Exit(1)
}
}// cmd/serve.go
var port int
var serveCmd = &cobra.Command{
Use: "serve",
Short: "Start the HTTP server",
RunE: func(cmd *cobra.Command, args []string) error {
fmt.Printf("Starting server on port %d...\n", port)
return startServer(port)
},
}
func init() {
serveCmd.Flags().IntVarP(&port, "port", "p", 8080, "port to listen on")
rootCmd.AddCommand(serveCmd)
}Key Features
- Subcommands — nested command structure (app cmd subcmd)
- Flag System — persistent and local flags with POSIX compatibility
- Auto Help — generated --help for every command
- Shell Completions — bash, zsh, fish, and PowerShell completions
- Argument Validation — built-in validators (ExactArgs, MinimumNArgs, etc.)
- Pre/Post Hooks — run code before/after command execution
- Cobra CLI — scaffolding tool to generate command boilerplate
- Viper Integration — seamless configuration file and env var binding
Comparison with Similar Tools
| Feature | Cobra | urfave/cli | Kong | Click (Python) | clap (Rust) |
|---|---|---|---|---|---|
| Language | Go | Go | Go | Python | Rust |
| Subcommands | Yes | Yes | Yes | Yes | Yes |
| Auto Help | Yes | Yes | Yes | Yes | Yes |
| Completions | All shells | Basic | Basic | Basic | All shells |
| Config Integration | Viper | Manual | Struct tags | Manual | Manual |
| Code Gen | cobra-cli | No | No | No | derive macros |
| Adoption | Dominant in Go | Popular | Growing | Dominant in Python | Dominant in Rust |
FAQ
Q: Cobra vs urfave/cli — which should I use? A: Cobra for larger applications with deep subcommand trees and config file support (via Viper). urfave/cli for simpler CLIs with a more lightweight API. Cobra is the standard for production Go CLIs.
Q: How do I add shell completions? A: Cobra auto-generates completion scripts. Add a "completion" command: rootCmd.AddCommand(completionCmd). Users run "mycli completion bash > /etc/bash_completion.d/mycli".
Q: Can I use Cobra without Viper? A: Yes. Cobra works standalone for flag parsing and command structure. Add Viper when you need config files (YAML, TOML, JSON), environment variables, or remote config.
Q: How do I test Cobra commands? A: Set rootCmd output to a buffer, execute with args, and check output. Example: rootCmd.SetArgs([]string{"serve", "--port", "9090"}) then rootCmd.Execute().
Sources
- GitHub: https://github.com/spf13/cobra
- Documentation: https://cobra.dev
- Created by Steve Francia (spf13)
- License: Apache-2.0