pflag

A drop-in replacement for Go's flag package that adds POSIX/GNU-style double-dash flags and shorthand letters.

Library
Go
vv1.0.10
2,782 stars
BSD 3-Clause License

Repository Health

Pre-computed score based on development activity, maintenance, community, maturity, and trend momentum. How we score it →
83 /100 Excellent
Development Activity 88
Maintenance 68
Community 76
Maturity 60
Momentum 40

Technical Analysis

AI-assessed by reading the actual repository — architecture, code quality, innovation, and documentation. How we score it →
80 /100 Excellent
Architecture 85
Code Quality 88
Innovation 55
Learning Curve 90

pflag is a drop-in replacement for Go’s standard library flag package, implementing POSIX/GNU-style command-line flag parsing. Where the standard flag package only understands single-dash flags, pflag adds double-dash long flags (--verbose), single-letter shorthand flags (-v), combinable boolean shorthands (-abc), and the -- argument terminator, matching the conventions Unix users expect from any serious CLI tool.

Because it mirrors the standard flag package’s API almost exactly, most codebases can switch by changing a single import alias (import flag "github.com/spf13/pflag"). It adds typed accessors (GetInt, GetString, etc.), flag deprecation and hiding, custom name-normalization functions, and structured error types with Unwrap support for use with Go’s errors.Is/errors.As. It has zero external dependencies and is the flag-parsing engine underneath Cobra, Kubernetes’ kubectl, Docker, Helm, and a large share of the Go CLI ecosystem.

What You Get

  • Long (--flag) and shorthand (-f) flag definitions via *P variants of every standard constructor (IntP, BoolVarP, VarP, etc.)
  • Combinable boolean shorthand flags on the command line (-abc instead of -a -b -c)
  • Typed value getters on a FlagSet (GetInt, GetString, GetDuration, …) so callers don’t need to track pointers
  • Structured, typed errors (NotExistError, ValueRequiredError, InvalidValueError, InvalidSyntaxError) that implement Unwrap for use with errors.Is/errors.As
  • Flag deprecation and hiding (MarkDeprecated, MarkHidden, MarkShorthandDeprecated) for maintaining CLI backward compatibility
  • Custom flag-name normalization (SetNormalizeFunc) for treating -, _, and . as equivalent, or aliasing renamed flags
  • Interop with Go’s native flag package via AddGoFlagSet, so third-party libraries that still register standard flags keep working

Common Use Cases

  • Building a CLI tool with GNU-style flags - a Go program wants --verbose/-v style flags instead of flag package’s single-dash-only syntax
  • Implementing subcommands - each subcommand gets its own independent pflag.FlagSet, the same pattern Cobra builds subcommand parsing on top of
  • Migrating from Go’s flag package with minimal changes - swap the import alias to flag "github.com/spf13/pflag" and existing flag.String()/flag.Parse() call sites keep compiling
  • Supporting deprecated or renamed flags without breaking scripts - MarkDeprecated and SetNormalizeFunc let a CLI evolve its flag names while still accepting the old ones
  • Bridging third-party flag registrations - AddGoFlagSet pulls in flags declared with the standard library’s flag package (e.g. from glog) into the same pflag.FlagSet

Under The Hood

Architecture

pflag centers on the FlagSet type (flag.go), which owns two maps keyed by flag name and shorthand plus an ordered slice for stable iteration, and every constructor (String, Int, BoolVarP, …) is a thin wrapper that allocates a typed Value implementation and registers it via FlagSet.VarP. Each primitive type (string, int, bool, duration, IP, slices of each, …) lives in its own file (string.go, int_slice.go, duration.go, ipnet.go, etc.) implementing the small Value interface (String(), Set(string) error, Type() string), so adding a new flag type is additive and doesn’t touch the parser core. Parsing itself walks os.Args-style slices token by token in parseArgs, dispatching to parseLongArg or parseShortArg depending on the leading dashes, and a package-level CommandLine FlagSet plus top-level functions (pflag.String(), pflag.Parse()) exist purely as convenience wrappers over an application-created FlagSet, matching the standard library’s ergonomics. This is a flat, single-responsibility layout: parsing, storage, and value types are cleanly separated, and nothing in the core loop depends on any one flag type.

Tech Stack

pflag is pure Go with zero runtime dependencies (go.mod declares only module github.com/spf13/pflag and go 1.12, no require block), which is deliberate for a library this deep in the Go CLI ecosystem’s dependency graph. It targets the standard library exclusively (fmt, strconv, errors, os, net, time) and its own golangflag.go shim provides one-way interop with the standard flag package rather than depending on it as a library. CI (.github/workflows/ci.yaml) runs the test suite against a matrix from Go 1.12 through current stable plus “oldstable”, reflecting a deliberate promise of long backward compatibility for a foundational dependency.

Code Quality

The repository carries roughly one test file per feature file (32 _test.go files against a similar count of implementation files), covering both individual value types (bool_test.go, ip_test.go, duration_slice_test.go) and end-to-end flag-parsing behavior (flag_test.go, printusage_test.go). CI runs tests with -race, and errors are represented as concrete exported types (NotExistError, ValueRequiredError, InvalidValueError, InvalidSyntaxError in errors.go) that implement the error interface and, where they wrap an underlying cause, Unwrap() error — enabling callers to use errors.As instead of string-matching error messages. Naming is consistent with the standard library’s flag package throughout (XxxVarP for pointer-binding shorthand variants, GetXxx for typed lookups), which lowers the cost of reading the source for anyone already familiar with flag.

What Makes It Unique

pflag’s specific niche is being the POSIX/GNU-flag layer that a large share of the Go CLI ecosystem (Cobra, and transitively kubectl, Helm, Docker CLI, and many others) is built on, while staying a near drop-in replacement for the standard library rather than a from-scratch flag-parsing API. Its typed-error refactor (NotExistError/ValueRequiredError/etc. with Unwrap support) is a comparatively recent addition that lets consuming tools programmatically distinguish failure modes instead of parsing human-readable strings, without changing the error text those tools already print to users.

Used by 33 apps in this directory

Go
100%
Apache 2.0

SpiceDB

Authentication · Databases · Security

7,169

An open source, Google Zanzibar-inspired authorization database that models permissions as relationships and evaluates fine-grained access checks at massive scale with single-digit millisecond latency.

View details
89
Repo Health
89
Technical
67
Dependency
Built with
Go 100%
Updated 1 weeks ago
C
74%
AGPL 3.0

TDengine

Databases

25,168

A high-performance, open-source time-series database built in C for IoT, connected vehicles, and industrial monitoring workloads, with built-in stream processing, caching, and data subscription.

View details
97
Repo Health
71
Technical
65
Dependency
Built with
C 74%
C++ 19%
Updated 1 weeks ago
Go
95%
Apache 2.0

TiDB

AI Development · Databases

40,672

AI-Native Distributed SQL Database for Agentic Workloads

View details
97
Repo Health
66
Technical
68
Dependency
Built with
Go 95%
Updated 1 weeks ago
Go
99%
Apache 2.0

Tusk

AI Code Assistants · Developer Tools · Devops

143

Record live API traffic and replay it as deterministic, sandboxed tests, plus AI code review and unit test generation, all from one Go CLI built by YC W2024's Use-Tusk.

View details
42
Repo Health
77
Technical
76
Dependency
Built with
Go 99%
Updated 5 months ago
Go
86%
Apache 2.0

Uncloud

Devops

5,572

Deploy and scale containerised apps across any servers without Kubernetes or Swarm overhead

View details
83
Repo Health
78
Technical
67
Dependency
Built with
Go 86%
Updated 2 weeks ago
Go
74%
AGPL 3.0

ZITADEL

Authentication

15,418

Open-source, API-first identity platform delivering multi-tenancy, Passkeys, OIDC, SAML, and SCIM without vendor lock-in.

View details
92
Repo Health
81
Technical
65
Dependency
Built with
Go 74%
TypeScript 12%
Updated 1 weeks ago

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