Skip to content

Comparison of Click and rich-click

rich-click is a thin wrapper around Click. The rich-click API is designed to mirror the Click API and intercept some of the calls to slightly different functions.

Everything available via import click is also available via import rich_click as click.

rich-click is designed to keep the additional API surface introduced on top of Click as lightweight as possible. In other words, rich-click does not introduce many additional concepts not already in Click. If you know Click, you already mostly know rich-click!

Click features that rich-click overrides

The only things that rich-click explicitly overrides in the high-level API are the decorators:

  • click.command()
  • click.group()
  • click.option() (+ its variants)
  • click.argument()

The only change to these decorators is that by default, their cls= parameters point to the rich-click implementations.

Note

There is also a thin wrapper around pass_context() to cast the click.Context type in the function signature to click.RichContext to assist with static type-checking with MyPy. Aside from different typing, there are no substantive changes to the pass_context() decorator.

Click features that rich-click does not override

Base Click command classes

You can still access the base Click classes by their original names:

from rich_click import Command, Group, Context

The above are the same as importing from click.

rich-click's subclasses all have the word Rich in front of them!

from rich_click import RichCommand, RichGroup, RichContext

Echo and interactive elements

rich-click deliberately does not enrich certain Click features:

click.echo()
click.echo_via_pager()
click.confirm()
click.prompt()

You are free to use these functions and they are available via import rich_click as click, but Rich's markup will not work with these functions because these functions are just the base Click implementations, without any changes.

This is a deliberate decision that we are unlikely to change in the future. We do not want to maintain a more spread-out API surface, and we encourage users to become comfortable using Rich directly; it's a great library and it's worth learning a little bit about it! If you'd like Rich markup for your echos and interactive elements, then you can:

Click Function Rich Replacement Rich Documentation
click.echo() rich.print() Quick start
click.echo_via_pager() rich.Console().pager() Console
click.confirm() rich.prompt.Confirm.ask() Prompt
click.prompt() rich.prompt.Prompt.ask() Prompt

Below is a side-by-side comparison of Click and Rich implementations of echos and interactive elements in rich-click:

import rich_click as click

@click.command("greet")
def greet():
    name = click.prompt(click.style("What is your name?", fg="blue"))

    if not click.confirm(click.style("Are you sure?", fg="blue")):
        click.echo(click.style("Aborting", fg="red"))
        return

    click.echo(click.style(f"Hello, {name}!", fg="green"))

if __name__ == "__main__":
    greet()
import rich_click as click
import rich
from rich.prompt import Confirm, Prompt

@click.command("greet")
def greet():
    name = Prompt.ask("[blue]What is your name?[/]")

    if not Confirm.ask("[blue]Are you sure?[/]"):
        rich.print("[red]Aborting[/]")
        return

    rich.print(f"[green]Hello, {name}![/]")

if __name__ == "__main__":
    greet()

Additional rich-click features

  • rich-click arguments can be given help= text:
    import rich_click as click
    
    @click.command()
    @click.argument("src", help="Source location")
    @click.argument("dest", help="Destination location")
    def move_item(src, dest):
        """Move an item from a src location to a dest location"""
        ...
    
  • rich-click commands can be given aliases, similar to other Click extensions (click-aliases, click-extra, cloup).
  • rich-click has themes to beautify all CLIs, whether you're an end-user or a CLI developer. More information about this is described in the Themes docs.
  • rich-click help text is formatted using highly configurable option panels and command panels:
    import rich_click as click
    
    @click.group()
    @click.option("--environment", help="Environment")
    @click.option("--log-level", help="Log level")
    @click.option_panel("Config",
                        options=["--environment", "--log-level"],
                        help="Global runtime configuration")
    @click.command_panel("Admin Commands",
                         commands=["user", "resource", "self"],
                         help="Commands available to administrators")
    def cli(environment, log_level):
        """My application"""
        ...
    
    More information about this is described in the Panels docs.
  • rich-click has a configuration object, RichHelpConfiguration(), that allows for control over how rich-click help text renders, so you are not locked into the defaults. More information about this is described in the Configuration docs.
  • rich-click comes with a CLI tool that allows you to convert regular Click CLIs into rich-click CLIs, and also lets you render your rich-click CLI help text as HTML, SVG, JSON, and trees. More information about this is described in the rich-click CLI docs, or you can run rich-click --help to view the CLI.