Colour conventions
Establish consistent colour semantics across your tool so users build reliable intuitions about what each colour means.
- Describe the standard colour-to-state mapping (green/yellow/red) and why it matches user expectations
- Explain how inconsistent colour use erodes user trust
- Apply colour consistently through a shared Rich Console or theme object
Colour is a signal. Like road signs, it only works when the mapping is consistent. Green means go. Red means stop. Yellow means caution. These associations are pre-loaded in every user's mind before they run your tool. Working with those associations makes your tool instantly legible. Fighting them forces users to learn a new vocabulary every time they encounter a coloured line.
The standard mapping
Most well-designed CLI tools converge on the same colour semantics:
| Colour | Meaning | Examples |
|---|---|---|
| Green | Success, OK, ready | Build passed, file written, test passed |
| Yellow | Warning, notice, something to check | Deprecated option, skipped file, slow |
| Red | Error, failure, action required | Exception, missing file, invalid input |
| Blue | Information, in progress | Connecting, loading, status message |
| Dim/grey | Secondary detail, less important text | File paths, timestamps, counts |
This is not a law — but deviating from it without a strong reason will confuse experienced CLI users who have internalised this convention from decades of tools that follow it.
The cost of inconsistency
Suppose your tool uses red for both errors and for "items that were deleted successfully." A user who sees red output stops and re-reads it every time, because they cannot trust the signal. The cognitive overhead compounds: every red line is a question mark until they decode the context.
Consistent colour removes that overhead. After the first run, users know without thinking: green lines are fine, red lines need attention. They can scan a hundred-line output in seconds.
Centralising your colour scheme
The easiest way to stay consistent is to define your status messages in one
place rather than sprinkling [bold green] markup throughout the code:
from rich.console import Console
console = Console()
def ok(msg: str) -> None:
console.print(f"[bold green]OK[/] {msg}")
def warn(msg: str) -> None:
console.print(f"[yellow]WARN[/] {msg}")
def error(msg: str) -> None:
console.print(f"[bold red]ERR[/] {msg}", stderr=True)Now every status line in your tool comes from one of these three functions. If you ever decide to change the styling — say, adding an icon or changing the label — you change it in one place.
Accessibility note
Some users have colour-vision deficiencies, and some terminals are used
without colour support. Never convey information through colour alone. The
examples above use OK, WARN, and ERR prefixes so the meaning is clear
even in a plain-text log. Colour reinforces meaning; it does not replace text.
Rich respects the NO_COLOR environment variable. When NO_COLOR is set,
Rich strips all colour automatically. This is a community standard for
accessibility and for CI environments. You get compliance for free.
Where to go next
Next: lab — rich tool — apply everything from this module by upgrading a plain-text CLI script to use Rich tables, progress bars, and error panels.