BenchmarkΒΆ
Feature comparison between Click Extra and competing CLI frameworks across ecosystems. The tables below track where Click Extra leads, where it matches, and where it can still improve.
Developer experienceΒΆ
β = built-in support, ~ = basic or partial support, N/A = not applicable (compiled language).
Feature |
|
|
|
|
|
|
|
|
|
|
|
|
|---|---|---|---|---|---|---|---|---|---|---|---|---|
Config file discovery |
β |
β |
β |
β |
||||||||
Config precedence chain |
β |
β |
~ |
β |
||||||||
Type-hint-driven params |
β |
β |
β |
β |
β |
|||||||
Option groups / constraints |
β |
β |
β |
β |
β |
~ |
β |
|||||
Persistent / inherited flags |
β |
N/A |
β |
β |
~ |
β |
β |
|||||
Lazy subcommand loading |
β |
N/A |
N/A |
β |
N/A |
|||||||
Parameter introspection |
β |
click-extra reads TOML, YAML, JSON, INI, and XML config files, including [tool.*] sections from pyproject.toml and remote URLs. Config-file precedence is layered through Clickβs default_map, so command-line flags and environment variables always win. The strict-check pipeline ships an extension mechanism so apps can validate data-keyed sub-tables alongside click-extraβs own CLI-flag checks. cobra achieves similar coverage through Viper (YAML, TOML, JSON, HCL, INI, env vars). Cyclopts supports TOML, YAML, JSON, and env vars. Cement uses INI by default with YAML and JSON via extensions. clap requires a companion crate for config file support.
End-user experienceΒΆ
Feature |
|
|
|
|
|
|
|
|
|
|
|
|
|---|---|---|---|---|---|---|---|---|---|---|---|---|
Colored help |
β |
~ |
~ |
β |
β |
β |
β |
β |
β |
|||
Command suggestions |
β |
β |
β |
β |
||||||||
Shell completion |
~ |
~ |
~ |
β |
~ |
β |
β |
β |
β |
~ |
β |
|
Man page generation |
β |
β |
||||||||||
Table / data output |
β |
β |
||||||||||
Timer / profiling |
β |
~ |
||||||||||
Telemetry control |
β |
~ |
~ |
|||||||||
Version with git metadata |
β |
~ |
~ |
~ |
~ |
~ |
click-extraβs colored help uses a theme system with semantic highlighting for options, choices, metavars, defaults, env vars, and subcommand names. Six built-in palettes ship out of the box (dark, light, dracula, monokai, nord, solarized_dark); users can override any slot of an existing palette or define brand-new themes directly in the CLIβs --config file ([tool.<cli>.themes.<name>]), with overrides scoped per-invocation so concurrent runs in the same process donβt bleed into each other. cobra only provides basic ANSI coloring. rich-click and Cyclopts use Rich for formatted help output but ship a single style; user-defined palettes require Python code. Shell completion in Click and click-extra covers command and option names; clap, cobra, bpaf, Cyclopts, and Typer add dynamic value completion and multi-shell auto-install. click-extra also offers --show-params, --time, --telemetry/--no-telemetry, --table-format, and git-aware --version out of the box.
Parser flag scopingΒΆ
Behavior when placing global flags before vs. after a subcommand:
Framework |
Global flags before subcommand |
|---|---|
|
β |
|
β |
|
β |
|
β |
|
β |
|
β |
|
β |
|
β |
|
β |
|
β |
|
Click (and click-extra, Cloup, rich-click, Typer) accepts global flags in both positions, the most permissive behavior. bpafβs #[bpaf(external)] fields are scoped inside the subcommand variant, so tool --flag value subcommand is rejected. Fire uses object traversal rather than subcommand parsing, so flag scoping does not apply.
Unique strengthsΒΆ
Features unique to click-extra or significantly stronger than all competitors:
Multi-format config with
pyproject.toml: no other framework reads[tool.*]frompyproject.tomlnatively. Cobra/Viper comes closest but targets Go projects.Help colorization with theme system: click-extra highlights options, choices, metavars, defaults, env vars, and subcommand names with configurable themes. Six built-in palettes (
dark,light,dracula,monokai,nord,solarized_dark) plus user-defined and partial-override themes declared directly in the CLIβs--configfile ([tool.<cli>.themes.<name>]). Theme overrides are scoped per invocation viactx.meta, so back-to-back runs in the same process donβt cross-contaminate. Other frameworks offer basic ANSI colors but not semantic highlighting, and none load user palettes from config.Table and data serialization:
print_table()andserialize_data()with 20+ output formats. Cement offers table output but with fewer format options and no serialization pipeline.Parameter introspection:
--show-paramsexposes every parameterβs value, source, default, and environment variable. No other framework offers this.Version with git metadata: template variables for branch, hash, date, tag, with pre-baking for compiled binaries (Nuitka, PyInstaller).
Configuration validation extension hook:
ConfigValidatorlets apps declare extension paths ([tool.<cli>.managers.<id>],[tool.<cli>.plugins], β¦) that click-extraβs strict check skips and the app validates with rootedValidationErrors.--validate-configcollects every error in one pass. No other framework exposes the strict-check pipeline this way.wrapsubcommand: applies click-extraβs help colorization, themes, and config loading to any installed Click CLI without touching its source code. The wrapped CLI inherits the--configtheme loader, so users can theme a third-party tool from their ownpyproject.toml.
Gaps and opportunitiesΒΆ
Man page generationΒΆ
cobra and bpaf generate man pages from the CLI definition. Clickβs maintainers closed the topic in 2018 (pallets/click#434), deferring to external tools. The third-party click-man package generates man pages from Click commands and is usable with click-extra today, though it has limitations: the last published release is 0.4.2 from 2021, it does not handle Clickβs \b formatting markers (click-contrib/click-man#9), breaks on Python 3.13 (click-contrib/click-man#72), and cannot discover dynamic subcommands (click-contrib/click-man#14, click-contrib/click-man#56). It also does not leverage click-extraβs richer metadata (option groups, config file paths, env vars, version templates).
Upstream, Click is redesigning its help output machinery (pallets/click#3089, pallets/click#561 with 14 thumbs-up) with a pluggable formatter system. This could eventually provide a cleaner data source for man page generation.
Persistent / inherited flagsΒΆ
cobraβs persistent flags propagate from a parent command to all subcommands automatically. Clickβs maintainers have consistently stated that options belong to the command they modify, and positional dependence (cli --opt subcmd vs cli subcmd --opt) is intentional (pallets/click#66, pallets/click#1034). The official workaround is custom decorators that apply the same options to multiple commands.
This is one of Clickβs most requested features. The highest-demand closed issues all center on the same family of problems: parent group options are invisible to subcommands (pallets/click#108, 9 thumbs-up), required group options block --help on child commands (pallets/click#814, 14 thumbs-up; pallets/click#295, 15 thumbs-up), and group options are lost in CommandCollection (pallets/click#347, 13 thumbs-up β closed as not_planned in September 2025, formalizing the rejection).
The ongoing parser rewrite (pallets/click#2205) and related PR for dynamic context parameters (pallets/click#2784) could eventually unblock this upstream, but both have been in progress since 2022 with no merge date in sight. click-extra could add a @persistent_option decorator (or a persistent=True kwarg on @option) that registers the option on the group and injects it into all subcommands at decoration time. The config file support already handles cross-command defaults; persistent flags would complete the story for the CLI layer.
Enhanced shell completionΒΆ
Clickβs built-in completion covers command and option names but has several known gaps. clap, cobra, bpaf, Cyclopts, and Typer all provide richer completion out of the box. The upstream issues below represent the main areas where click-extra could close the gap:
Context-dependent completions (pallets/click#2303, pallets/click#2184, pallets/click#928): the Context object during shell completion is missing already-parsed parameter values, so completions cannot depend on previous arguments (like completing tags based on a previously typed project name). This is the highest-demand open completion issue (14+ thumbs-up). click-extra could override the completion resolution to populate ctx.params properly.
Broken --option=value completion (pallets/click#2847): completing --option=val<TAB> is broken in both bash and zsh. The = separator parsing in _resolve_context needs fixing.
Default callbacks evaluated during completion (pallets/click#2614): since Click 8.0, default value callbacks run during tab-completion even when resilient_parsing should suppress them. Makes completion slow for apps with expensive defaults.
Fish multiline help (pallets/click#3043): help text containing newlines used to break fish completion. Fixed upstream in pallets/click#3126 (merged 2026-04-29), which also closes the bug report. Once click-extraβs Click floor bumps to the release that ships the fix, fish completion handles multi-line help text out of the box and no click-extra workaround is needed.
Enum Choice mismatch (pallets/click#3015): click.Choice(MyEnum) completes MyEnum.foo instead of foo because completion skips the normalization the Choice type applies at parse time.
Additional shells rejected upstream (pallets/click#2888, pallets/click#3188, pallets/click#2672): Click explicitly rejected adding nushell, Carapace, and PowerShell completion to core β all three issues are closed as not_planned, so the door is closed upstream and remains a click-extra opportunity. click-extra could provide NushellComplete and PowerShellComplete classes, and generate Carapace YAML from its parameter introspection.
Multi-shell auto-install: Typerβs --install-completion detects the current shell and installs the completion script automatically. click-extra could bundle a similar @completion_option.
ActivityΒΆ
PopularityΒΆ
DistributionΒΆ
MetadataΒΆ
Excluded frameworksΒΆ
Note
argh (~400 stars) is not included. No commits or releases since July 2024. Recent issues from 2026 have no maintainer responses.
Note
Cleo (~1,300 stars) is not included. Its last release (2.1.0) was October 2023 and the 3.0 rewrite has stalled indefinitely. Recent repository activity is limited to automated pre-commit updates. Cleo is tightly coupled to Poetry and not independently maintained.
Note
docopt-ng (the maintained fork of the original docopt with ~8,000 stars) is not included. The Jazzband organization that maintained the fork announced its wind-down in March 2026, and docopt-ng is sunsetting along with it. The original docopt has been stale since 2021. While docoptβs docstring-driven approach to CLI definition was historically influential, no actively maintained Python implementation remains.