Rich
Rich is a Python library for writing styled text, tables, progress bars, syntax-highlighted code, Markdown, and tracebacks to the terminal. It works on Linux, macOS, and Windows (true color on new Windows Terminal; 16-color on classic cmd.exe). Current version is 14.3.3 (released 2026-02-19); the project follows an active release cadence with frequent patch and minor releases under the Textualize organization.
Warnings
- breaking v14.0.0 changed how NO_COLOR and FORCE_COLOR are interpreted: an empty string value for either env var is now treated as disabled (falsy), not enabled. Code or CI configs that set NO_COLOR= or FORCE_COLOR= (empty) to toggle color will behave differently.
- gotcha Square brackets in printed strings are parsed as markup tags. Printing user-supplied or dynamic data containing brackets (e.g. log messages, file paths, regex patterns) can silently swallow content or raise MarkupError.
- gotcha RichHandler does not enable Console Markup in log messages by default (markup=False). Enabling markup=True on the handler is unsafe if any dependency logs strings containing square brackets.
- gotcha Rich never automatically installs its traceback handler. If you see Rich-style tracebacks unexpectedly, a third-party library is calling rich.traceback.install() — not Rich itself.
- gotcha Progress (and Live) cannot be nested prior to v14.1.0. Using a progress bar inside another Progress or Live context (e.g. inside a status spinner) raised a RuntimeError.
- gotcha In CI/GitHub Actions, Rich outputs plain text because the environment is not a TTY. Setting FORCE_COLOR= (empty) no longer forces color in v14+.
- deprecated RenderGroup and render_group were renamed to Group and group in an earlier release. The old names were kept for compatibility but are slated for removal.
Install
-
pip install rich -
uv add rich
Imports
- Console
from rich.console import Console
- print
from rich import print
- Table
from rich.table import Table
- Progress / track
from rich.progress import Progress, track
- RichHandler
from rich.logging import RichHandler
- Syntax
from rich.syntax import Syntax
- Markdown
from rich.markdown import Markdown
- Traceback install
from rich.traceback import install; install()
- escape
from rich.markup import escape
- Live
from rich.live import Live
Quickstart
import logging
import time
from rich.console import Console
from rich.logging import RichHandler
from rich.markup import escape
from rich.progress import track
from rich.syntax import Syntax
from rich.table import Table
# -- Console & markup --
console = Console()
console.print("[bold magenta]Rich[/bold magenta] is working! :tada:")
# -- Safe interpolation of untrusted strings --
user_input = "[blink]injected[/blink]"
console.print(f"Hello, {escape(user_input)}!")
# -- Table --
table = Table(title="Languages")
table.add_column("Name", style="cyan")
table.add_column("Paradigm", style="green")
table.add_row("Python", "Multi-paradigm")
table.add_row("Haskell", "Functional")
console.print(table)
# -- Syntax highlighting --
code = "def greet(name):\n return f'Hello, {name}!'"
syntax = Syntax(code, "python", theme="monokai", line_numbers=True)
console.print(syntax)
# -- Progress bar --
for _ in track(range(5), description="Processing..."):
time.sleep(0.1)
# -- stdlib logging integration --
logging.basicConfig(
level="INFO",
format="%(message)s",
datefmt="[%X]",
handlers=[RichHandler()],
)
log = logging.getLogger("rich")
log.info("All done.")