How to Design Great CLI Apps with Python
Command Line Interfaces (CLIs) are the bread and butter of developer efficiency. While Graphical User Interfaces (GUIs) are great for end-users, CLIs are often faster and more scriptable for developers. However, writing a CLI isn't just about parsing arguments; it's about creating a tool that is intuitive, helpful, and pleasant to use.
As a junior developer, moving beyond simple scripts to robust CLI applications is a major step up. Here is how to design great CLI apps using Python.
1. Prioritize Developer Experience (DX)
Just because a tool runs in a terminal doesn't mean it should be ugly or confusing. A great CLI adheres to the Principle of Least Astonishment.
- Help Flags: Always ensure your app responds to
--helpwith clear instructions. - Sensible Defaults: Don't force the user to type 10 arguments if 9 of them usually have the same value.
- Standard Output: Send data to
stdoutand errors tostderr. This allows users to pipe your output into other tools safely.
2. Choosing the Right Library: Typer
Python comes with a built-in library called argparse. While powerful, it requires a lot of boilerplate code.
For modern Python development, Typer is the gold standard. It is built on top of the popular library Click but leverages Python type hints to define arguments automatically.
Here is how simple a CLI is with Typer:
import typer
def main(name: str, formal: bool = False):
if formal:
typer.echo(f"Good day to you, {name}.")
else:
typer.echo(f"Hey {name}!")
if __name__ == "__main__":
typer.run(main)
With just that code, Typer automatically generates help text, handles boolean flags (--formal), and validates input types.
3. Making it Interactive and Beautiful with 'Rich'
The terminal used to be monochrome, but it doesn't have to be. To make your CLI "great" rather than just "functional," you need Rich.
Rich is a Python library for rich text and beautiful formatting in the terminal. It creates progress bars, markdown rendering, syntax highlighting, and tables with almost zero effort.
Here is an example of printing a table of data:
from rich.console import Console
from rich.table import Table
console = Console()
table = Table(title="Server Status")
table.add_column("ID", style="cyan", no_wrap=True)
table.add_column("Status", style="magenta")
table.add_column("IP Address", justify="right", style="green")
table.add_row("101", "Active", "192.168.1.1")
table.add_row("102", "Offline", "192.168.1.2")
console.print(table)
4. Interactive Prompts
Sometimes you need to ask the user for input dynamically (like a confirmation Are you sure? [y/N]).
While you can use the built-in input(), it is brittle. Libraries like Questionary or rich prompts allow you to create select lists, checkboxes, and password inputs easily.
import questionary
flavor = questionary.select(
"What is your favorite flavor?",
choices=[
"Chocolate",
"Vanilla",
"Strawberry",
]
).ask()
print(f"You chose {flavor}")
Summary
To build a CLI that other developers will love:
- Use Typer for argument parsing to save time and reduce bugs.
- Use Rich to provide visual feedback (colors, tables, progress bars).
- Respect the user by providing help text and standard exit codes.
Great tools are a joy to use. With Python's ecosystem, you can build professional-grade CLIs in minutes.

