Cobra — Structure#
Layout pattern#
Flat Library — All core source lives in the root package (github.com/spf13/cobra). There is no cmd/, internal/, or pkg/ hierarchy. A single subpackage (doc/) provides optional documentation generation utilities. This is the simplest possible Go library layout, chosen deliberately for a focused, stable API.
Directory map#
cobra/
├── *.go # Core library — all public API (package cobra)
├── doc/ # Documentation generation subpackage (package doc)
│ ├── man_docs.go # Generate man pages from Command tree
│ ├── md_docs.go # Generate Markdown docs
│ ├── rest_docs.go # Generate reStructuredText docs
│ ├── yaml_docs.go # Generate YAML docs
│ └── util.go # Shared doc-gen helpers
├── assets/ # Static project assets (logo image only)
├── site/ # Hugo-based documentation website source
│ └── content/ # Markdown content for completions and docgen docs
├── .github/
│ └── workflows/ # CI: test.yml (Go test matrix), labeler.yml
├── Makefile # Build/test targets
├── go.mod / go.sum # Module definition
└── README.md # User-facing documentationEntry points#
None. Cobra is a pure library with no main.go. It is imported and used by consuming applications. There are no binaries produced.
Package organization#
Root package (
github.com/spf13/cobra): The entire public library surface. Contains:command.go— the centralCommandstruct and its ~90 methods (Execute, AddCommand, flag accessors, etc.)cobra.go— package-level utilities (template helpers, OnInitialize, MousetrapHelpText)args.go— positional argument validators (NoArgs, ArbitraryArgs, MinimumNArgs, ExactArgs, etc.)completions.go— shell completion engine andCompletionOptionsshell_completions.go— shared completion helper logicbash_completions.go/bash_completionsV2.go— Bash completion script generatorszsh_completions.go— Zsh completion script generatorfish_completions.go— Fish completion script generatorpowershell_completions.go— PowerShell completion script generatoractive_help.go— ActiveHelp annotation support (dynamic completion hints)flag_groups.go— mutually exclusive and required-together flag group logiccommand_win.go/command_notwin.go— platform-specific terminal handling (Windows mousetrap detection vs. no-op)
doc/subpackage (github.com/spf13/cobra/doc): Documentation generators. Consumers import this separately to generate CLI reference docs in various formats. It depends on the parent cobra package but the parent does not depend on it — clean one-way dependency.Internal packages: None. No
internal/directory.Public packages (pkg/): None. No
pkg/directory.Layering: Effectively two layers — the core library (root package) and the optional doc-gen utility (
doc/). The root package itself is flat: no internal layering between files. Feature grouping is conveyed by filename convention (e.g., all shell-specific completion code is isolated to per-shell files), not package hierarchy.
Build system#
- Build tool: Make (
Makefile) - Key targets:
make/make all— runsfmt+testmake fmt— checks formatting withgofmtmake test—go test -v ./...make lint—golangci-lint runmake richtest— test withkyoh86/richgofor prettier outputmake install_deps—go get -v ./...
- CI: GitHub Actions (
test.yml) runs tests across multiple Go versions;labeler.ymlauto-labels PRs - Docker: No Dockerfile; not applicable for a library
- Releases: No goreleaser config visible; releases appear to be tag-based via GitHub
Notable structural decisions#
Everything in one package: With only ~25 non-test
.gofiles in the root, there was never pressure to split into sub-packages. This minimizes import paths for consumers (justcobra, nevercobra/commandorcobra/flags) and keeps the entire API discoverable in one place.Completions as first-class citizens alongside core code: Rather than putting shell completions in a
completions/subpackage, they live alongsidecommand.goin the root. This reflects a philosophical stance that completions are part of the core library contract, not an add-on.doc/as a separate importable package: Documentation generation is cleanly separated so that consumers who don’t need it don’t pay the dependency cost (go-md2man,yaml). This is a thoughtful library design decision.Platform-specific files via build constraints:
command_win.go(mousetrap check for Windows) andcommand_notwin.go(no-op stub) use Go’s filename-based build constraint convention — clean without any//go:buildproliferation in the main files.No
internal/package: Every exported symbol in the root is intentionally public API. This is consistent with a stable library that has had a large public surface for over a decade. Nothing is hidden — the library trusts its consumers.