Modern type-safe Typer CLI patterns with type hints, Enums, and sub-apps. Use when building CLI applications, creating Typer commands, implementing type-safe CLIs, or when user mentions Typer, CLI patterns, type hints, Enums, sub-apps, or command-line interfaces.
View on GitHubvanman2024/cli-builder
cli-builder
plugins/cli-builder/skills/typer-patterns/SKILL.md
January 22, 2026
Select agents to install to:
npx add-skill https://github.com/vanman2024/cli-builder/blob/main/plugins/cli-builder/skills/typer-patterns/SKILL.md -a claude-code --skill typer-patternsInstallation paths:
.claude/skills/typer-patterns/# typer-patterns
Provides modern type-safe Typer CLI patterns including type hints, Enum usage, sub-app composition, and Typer() instance patterns for building maintainable command-line applications.
## Core Patterns
### 1. Type-Safe Commands with Type Hints
Use Python type hints for automatic validation and better IDE support:
```python
import typer
from typing import Optional
from pathlib import Path
app = typer.Typer()
@app.command()
def process(
input_file: Path = typer.Argument(..., help="Input file path"),
output: Optional[Path] = typer.Option(None, help="Output file path"),
verbose: bool = typer.Option(False, "--verbose", "-v"),
count: int = typer.Option(10, help="Number of items to process")
) -> None:
"""Process files with type-safe parameters."""
if verbose:
typer.echo(f"Processing {input_file}")
```
### 2. Enum-Based Options
Use Enums for constrained choices with autocomplete:
```python
from enum import Enum
class OutputFormat(str, Enum):
json = "json"
yaml = "yaml"
text = "text"
@app.command()
def export(
format: OutputFormat = typer.Option(OutputFormat.json, help="Output format")
) -> None:
"""Export with enum-based format selection."""
typer.echo(f"Exporting as {format.value}")
```
### 3. Sub-Application Composition
Organize complex CLIs with sub-apps:
```python
app = typer.Typer()
db_app = typer.Typer()
app.add_typer(db_app, name="db", help="Database commands")
@db_app.command("migrate")
def db_migrate() -> None:
"""Run database migrations."""
pass
@db_app.command("seed")
def db_seed() -> None:
"""Seed database with test data."""
pass
```
### 4. Typer() Instance Pattern
Use Typer() instances for better organization and testing:
```python
def create_app() -> typer.Typer:
"""Factory function for creating Typer app."""
app = typer.Typer(
name="myapp",
help="My CLI application",
add_completion=True,
no_args_is_help=True
)