CLI tool
ewels/rich-click avatar
ewels/rich-click

rich-click: click help output rendered through Rich

Format click help output nicely with rich.

825 stars53 forksPythonMIT

At a glance

What is it?
rich-click wraps Click so that help text and error messages come out styled, and the adoption cost is a single import line in the common case. It also ships a CLI that reformats someone else's Click or Typer application, which is the feature that makes it useful to teams who do not control the source.
Who is it for?
Adopt rich-click if you build a Click or Typer CLI and want readable, coloured help without giving up the standard API, especially if you also want themes, panels or HTML export of your help text. Do not adopt it if your CLI relies on help output being plain text that another program parses, since the whole point is to insert styling.
Can I use it commercially?
Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 21 days ago.
What is it written in?
Mainly Python, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.

Editorial analysis

The common case is one import line

rich-click is a wrapper around Click that renders help output nicely using Rich, and its selling point is that the intention is attractive help output from Click with minimal customization required. Click is what the project calls a Python package for creating beautiful command line interfaces, and Rich is what it calls a Python library for rich text and beautiful formatting in the terminal. The adoption path is deliberately boring. You replace import click with import rich_click as click in your existing CLI:

python
import rich_click as click

@click.command()
@click.option("--count", default=1, help="Number of greetings.")
@click.option("--name", prompt="Your name", help="The person to greet.")
def hello(count, name):
    """Simple program that greets NAME for a total of COUNT times."""
    for _ in range(count):
        click.echo(f"Hello, {name}!")

if __name__ == '__main__':
    hello()

Because the module exposes the same names, the decorators, the echo helper and the group and command classes are the ones you already use. There is no new object model to learn, and nothing in your command implementations has to change. The features it adds on top are Rich formatting of both help and error messages, over 100 themes settable by developers and end-users through the RICH_CLICK_THEME environment variable, grouping of commands and options into named panels, extensive customization options, export of help text as HTML or SVG, and IDE autocomplete of Click decorators. The autocomplete point is small but telling: it is the kind of friction that only exists if the author cared about the developer experience as well as the end user's screen.

A second path keeps plain click importable alongside

If you would rather not shadow the click namespace, there is a declarative route. You use RichGroup or RichCommand through the cls argument, which means the unmodified click package can stay in use in parallel:

python
import click
from rich_click import RichCommand

@click.command(cls=RichCommand)
def main():
    """My amazing tool does all the things."""

This matters more than it sounds. A library that other people import, or an application that pulls in a third-party plugin built on click, cannot simply redefine what the name click means at import time. The declarative form keeps the change local to the command that needs it, and a project can mix the two approaches. The repository examples make the range visible. There are thirteen numbered examples covering the simple case, the declarative case, command groups and sorting, rich markup, markdown in help text, arguments, custom errors, metavars with and without defaults, environment variables, table styles, a hello world, a simple theme and an async example. That list is a better map of the feature surface than the feature bullets, and the theme example in particular shows that the styling is meant to be a design decision rather than a single look.

The CLI tool reformats other people's applications

The feature that distinguishes rich-click from a themed replacement is the command line wrapper that formats the Click help output from any package that uses Click, and the README notes it is aimed at other people's Click and Typer CLIs. You prefix rich-click to your normal command:

console
$ rich-click awesometool --help

Usage: awesometool [OPTIONS]
..more richified output below..

That is a different product decision from shipping a library. A team that maintains a CLI can edit its source and adopt rich-click directly, so the wrapper is mostly for everyone else: developers trying out third-party tools, documentation writers capturing help output, and anyone who wants to see whether a tool's help reads better before deciding to fork it. The wrapper entry point is declared in the project metadata as scripts.rich-click = rich_click.cli:main, so it is a console script installed by pip rather than something you invoke by path.

Themes, panels and HTML export are the differentiation

Beyond the colours, the features that a plain Click application does not have are themes, panels and export. Over 100 themes can be set by developers and end-users, with the environment variable RICH_CLICK_THEME as the end-user lever, which means a team can ship a default look while letting individual users override it. Panels let you group commands and options into named sections, which is how a CLI with fifty options avoids presenting a wall of alphabetically sorted flags, and the 03_groups_sorting.py example is the one to look at if you want to see what that looks like. Export of help text as HTML or SVG is aimed at documentation and it is a small feature with a clear use: you generate a styled, shareable artifact rather than a screenshot of a terminal. The README describes the customization options as composing help text however you would like, and the examples directory backs that up with dedicated files for rich markup, markdown, custom errors, metavars, environment variables and table styles.

Where it does not fit

There is one structural limitation, and it is the mirror image of the feature. rich-click changes the bytes your program writes to standard output. If anything in your pipeline parses that output, if a script greps for an option name in a usage line, if a test asserts on the exact help text, or if your program is meant to be read by a machine rather than a person, styled output will break it. The README does not document a plain or no-color mode for that case, and it does not describe what happens when output is not a terminal. The other limitation is dependency weight. Rich is a substantial library, and the manifest requires rich>=12 alongside click>=8, plus colorama on Windows and typing-extensions on Python below 3.11. If you are building a small script that only needs to print one line, pulling in Rich and rich-click to decorate a usage message is a poor trade. For a CLI with a real command surface, where help output is a large part of the product, the cost is clearly worth it.

Dependency and compatibility floor

The manifest is small and explicit. rich-click requires Python 3.10 or newer and is classified as OS Independent and Development Status 3 - Alpha, with classifiers for Python 3.10 through 3.14. The runtime dependencies are click>=8, rich>=12, colorama on Windows only, and typing-extensions on Python versions below 3.11. There is an optional async extra that pulls anyio and asyncclick, with separate version floors for Python above and below 3.11, and the async support has its own test file in the dev group. Two housekeeping files in the repository are worth noting for anyone contributing. There is a.rich-codex.yml and a prek.toml, which is the pre-commit configuration, replacing the older.pre-commit-config.yaml convention. The build backend is setuptools with a dynamic version, and the documentation is built with mkdocs from a mkdocs.yml at the root, with the published site at ewels.github.io/rich-click.

MIT licensed, 1.9 line, one maintainer and a second

The licence is MIT with the LICENSE file at the root, and the project states it plainly in the README. The maintainers listed in the manifest are Phil Ewels and Daniel Reeves, with Ewels also listed as the author, and the repository is hosted under the ewels organisation with the documentation site on the ewels.github.io path. The release history is steady. Version 1.9.7 on 2026-01-31, 1.9.8 on 2026-05-28 and 1.9.9 on 2026-09-05, with the last push on 2026-10-01 and the repository not archived. That is a mature cadence for a package whose whole job is presentation. The alpha development status is worth holding in mind against that: the classifier says 3 - Alpha, which is what a project that reserves the right to change rendering behaviour says about itself, and for a package that wraps another one, that is a reasonable thing to signal. The CHANGELOG.md at the root and the CONTRIBUTING.md next to it are where you would look before an upgrade.

Editorial conclusion

Adopt rich-click if you build a Click or Typer CLI and want readable, coloured help without giving up the standard API, especially if you also want themes, panels or HTML export of your help text. Do not adopt it if your CLI relies on help output being plain text that another program parses, since the whole point is to insert styling. Before you commit, check the Rich version your environment pins against the rich>=12 requirement, try the rich-click prefix on a tool you already use to see how the rendering lands in your terminal, and read the CHANGELOG.md, since the project is on the 1.9 line and the last push was on 2026-10-01.

Frequently asked questions

What is rich-click?

It is an MIT licensed wrapper around Click that renders help output and error messages with Rich. It is published on PyPI as rich-click, requires Python 3.10 or newer, and provides the same API as Click so that usage is simply import rich_click as click.

How do I use rich-click with an existing Click CLI?

Replace your import click with import rich_click as click, or keep plain click and pass cls=RichCommand or RichGroup to the decorator. The first approach changes nothing else in your code, the second lets you keep the unmodified click package in use in parallel.

Can rich-click format the help output of another program?

Yes. It ships a CLI tool that formats the Click help output from any package that uses Click, and the README mentions Typer CLIs as well. You prefix rich-click to your normal command, for example rich-click awesometool --help.

How do I change the colours rich-click uses?

There are over 100 themes, set by developers and by end-users, and the end-user lever is the RICH_CLICK_THEME environment variable. The 12_theme_simple.py example in the repository examples directory shows the theme configuration.

Official sources

  1. ewels/rich-click on GitHub
  2. License: MIT
  3. Project website
  4. README
  5. Releases
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/ewels-rich-click.svg)](https://hysenlabs.com/projects/ewels-rich-click)

Was this useful?