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
71%
Other

Convoy

Developer Tools · Devops

2,883

Convoy is an open-source, cloud-native webhooks gateway that ingests events over HTTP or straight from Kafka, SQS, Google Pub/Sub, and RabbitMQ, then reliably delivers them to subscriber endpoints with signed payloads, automatic retries, circuit breaking, and JavaScript-based transformations.

View details
88
Repo Health
81
Technical
66
Dependency
Built with
Go 71%
TypeScript 15%
HTML 12%
Updated 1 weeks ago
Go
75%
MIT

Digger

Automation · Developer Tools · Devops

5,057

Run Terraform and OpenTofu natively inside your existing CI pipeline — no separate runners, no third-party secrets, no extra compute costs.

View details
78
Repo Health
73
Technical
66
Dependency
Built with
Go 75%
TypeScript 15%
Updated 1 weeks ago
Go
97%
Apache 2.0

Docker (Moby)

Developer Tools · Devops

72,199

The open-source container engine at the heart of Docker — a modular toolkit of runtime, build, and networking components for assembling container-based systems.

View details
97
Repo Health
86
Technical
69
Dependency
Built with
Go 97%
Updated 1 weeks ago
Go
49%
MIT

Dokku

Devops · Hosting Control Panel

32,202

The smallest PaaS implementation you've ever seen — deploy apps via git push using Docker and Heroku buildpacks on your own server.

View details
93
Repo Health
85
Technical
66
Dependency
Built with
Go 49%
Shell 48%
Updated 6 days ago
Go
85%
Apache 2.0

frp

Networking

110,102

A fast reverse proxy that exposes local servers behind NAT or firewalls to the public internet with multi-protocol support.

View details
95
Repo Health
82
Technical
71
Dependency
Built with
Go 85%
Vue 11%
Updated 1 weeks ago
TypeScript
47%
AGPL 3.0

Grafana

Analytics · Monitoring

77,469

The open-source observability platform that unifies metrics, logs, and traces from any data source into dynamic, queryable dashboards.

View details
95
Repo Health
91
Technical
63
Dependency
Built with
TypeScript 47%
Go 47%
Updated 6 days ago
Go
97%
Apache 2.0

infracost

Developer Tools · Devops

12,585

Infracost shows cloud cost estimates for Terraform, CloudFormation, and AWS CDK before you deploy — in your terminal, editor, AI coding agent, and pull requests.

View details
83
Repo Health
78
Technical
68
Dependency
Built with
Go 97%
Updated 1 weeks ago
Go
95%
MIT

cli

Developer Tools · Team Chat

17,815

The official Lark/Feishu CLI tool built for both humans and AI agents, delivering 200+ commands and 26 AI agent skills across 18 business domains from messaging and calendar to docs, sheets, and approvals.

View details
84
Repo Health
83
Technical
75
Dependency
Built with
Go 95%
Updated 1 weeks ago
Go
97%
MIT

Formance Ledger

Databases · Developer Tools · Invoicing Finance

1,448

The programmable open source core ledger for fintech — build money-moving applications with atomic multi-posting transactions, account-based modeling, and Numscript, a built-in DSL for financial logic.

View details
91
Repo Health
8
Technical
68
Dependency
Built with
Go 97%
Updated 6 days 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