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 documentation

Entry 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 central Command struct 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 and CompletionOptions
    • shell_completions.go — shared completion helper logic
    • bash_completions.go / bash_completionsV2.go — Bash completion script generators
    • zsh_completions.go — Zsh completion script generator
    • fish_completions.go — Fish completion script generator
    • powershell_completions.go — PowerShell completion script generator
    • active_help.go — ActiveHelp annotation support (dynamic completion hints)
    • flag_groups.go — mutually exclusive and required-together flag group logic
    • command_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 — runs fmt + test
    • make fmt — checks formatting with gofmt
    • make testgo test -v ./...
    • make lintgolangci-lint run
    • make richtest — test with kyoh86/richgo for prettier output
    • make install_depsgo get -v ./...
  • CI: GitHub Actions (test.yml) runs tests across multiple Go versions; labeler.yml auto-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#

  1. Everything in one package: With only ~25 non-test .go files in the root, there was never pressure to split into sub-packages. This minimizes import paths for consumers (just cobra, never cobra/command or cobra/flags) and keeps the entire API discoverable in one place.

  2. Completions as first-class citizens alongside core code: Rather than putting shell completions in a completions/ subpackage, they live alongside command.go in the root. This reflects a philosophical stance that completions are part of the core library contract, not an add-on.

  3. 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.

  4. Platform-specific files via build constraints: command_win.go (mousetrap check for Windows) and command_notwin.go (no-op stub) use Go’s filename-based build constraint convention — clean without any //go:build proliferation in the main files.

  5. 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.