typer-extensions
Command aliases for Typer CLI applications with grouped help text display
Overview
typer-extensions extends Typer to provide simple drop-in support for command aliases. Instead of duplicating commands, hiding commands, or maintaining wrapper functions, define aliases directly and have them displayed cleanly in help text.
100% backwards compatible with Typer & existing Typer apps!
The Problem
Standard Typer requires duplicating or hiding commands to create aliases:
from typer import Typer
app = Typer()
@app.command()
def list_items():
"""List all items."""
print("Listing...")
# Registered as separate command, hidden in help
@app.command("ls", hidden=True)
def ls_items():
list_items()
@app.command("l")("list") # Duplicate!
Help output:
Commands:
list List all items.
l List all items.
Issues:
- Code duplication
- Help text shows commands & aliases separately
- Hidden 'aliases' not shown in help text
- Maintenance burden
The Solution
With typer-extensions:
from typer_extensions import ExtendedTyper
app = ExtendedTyper()
@app.command("list", aliases=["ls", "l"])
def list_items():
"""List all items."""
print("Listing...")
Help output:
Commands:
list (ls, l) List all items.
All work identically:
app list
app ls
app l
Features
✨ Decorator-based alias registration - Clean, intuitive syntax for commands and sub-command groups
🔧 Programmatic API - Dynamic alias management at runtime
📋 Grouped help display - Aliases shown with their primary command
⚙️ Highly configurable - Customise format, separators, truncation
🎯 Type-safe - Full type hints and editor support
🔄 Fully backwards compatible - Works with all Typer/Click features and existing Typer apps
✅ Shell completion ready - Alias support doesn't interfere with existing shell completion
🧪 Well-tested - Tested on Python 3.11-3.14 with 100% test coverage
Installation
pip install typer-extensions
Quick Start
Basic Usage
from typer_extensions import ExtendedTyper
app = ExtendedTyper()
@app.command("list", aliases=["ls", "l"])
def list_items():
"""List all items."""
print("Listing items...")
@app.command("delete", aliases=["rm", "remove"])
def delete_item(name: str):
"""Delete an item."""
print(f"Deleting {name}")
if __name__ == "__main__":
app()
Run it:
$ python app.py --help
Commands:
list (ls, l) List all items.
delete (rm, remove) Delete an item.
$ python app.py ls
Listing items...
$ python app.py rm test.txt
Deleting test.txt
Drop-in Compatibility
Have an existing Typer project? Add alias support without changing your code:
# Before (regular Typer)
from typer import Typer
app = Typer()
# After (with typer-extensions)
from typer_extensions import ExtendedTyper
app = ExtendedTyper()
# That's it! Everything else stays the same.
# Existing commands, shell completion and help text configuration still work exactly as before.
Once migrated, you can add aliases to new commands using @app.command(aliases=[]), or to existing commands using the programmatic API.
Advanced Features
Programmatic alias management:
# Add aliases dynamically
app.add_alias("list", "dir")
# Remove aliases
app.remove_alias("dir")
# Query aliases
aliases = app.get_aliases("list") # ["ls", "l"]
Custom help formatting:
app = ExtendedTyper(
alias_display_format="[{aliases}]", # Use brackets
alias_separator=" | ", # Pipe separator
max_aliases_inline=2, # Show max 2, then "+N more"
)
Configuration-based aliases:
# Load aliases from config
config = {"list": ["ls", "l", "dir"]}
for cmd, aliases in config.items():
for alias in aliases:
app.add_alias(cmd, alias)
Documentation
📚 User Guide - Tutorials and common patterns
📖 API Reference - Complete API documentation
🔄 Migration Guide - Migrating from standard Typer
Examples
All examples are in the examples/ directory:
- basic_usage.py - Simple CLI with aliases
- advanced_usage.py - Git-like CLI with options
- programmatic_usage.py - Dynamic alias management
- help_formatting.py - Customising help display
- argument_option_usage.py - Using Typer's Argument & Option
Run any example:
python examples/basic_usage.py --help
python examples/basic_usage.py ls
Real-World Use Cases
Git-like CLI
@app.command("checkout", aliases=["co"])
def checkout(branch: str):
"""Switch branches."""
...
@app.command("status", aliases=["st"])
def status():
"""Show status."""
...
Package Manager
@app.command("install", aliases=["i", "add"])
def install(package: str):
"""Install a package."""
...
@app.command("remove", aliases=["rm", "uninstall"])
def remove(package: str):
"""Remove a package."""
...
Cross-Platform Commands
@app.command("list")
def list_files():
"""List files."""
...
# Add platform-specific aliases
if platform.system() == "Windows":
app.add_alias("list", "dir")
else:
app.add_alias("list", "ls")
API Overview
Decorator Registration
@app.command(name, aliases=[...])
Programmatic Registration
app.add_command(func, name, aliases=[...])
Sub-Application Aliases
app.add_typer(sub_app, name="remote", aliases=["rem"])
Alias Management
app.add_alias(command, alias) # Add alias
app.remove_alias(alias) → bool # Remove alias
app.get_aliases(command) → list # Query aliases
app.list_commands_with_aliases() → dict # All mappings
Configuration
ExtendedTyper(
alias_case_sensitive=None, # Case-sensitive (default True, matching Typer)
show_aliases_in_help=True, # Display aliases in help
alias_display_format="({aliases})", # Display format
alias_separator=", ", # Between aliases
max_num_aliases=3, # Before truncation
)
Development
Setup
Standard setup with pip:
git clone https://github.com/rdawebb/typer-extensions.git
cd typer-extensions
python -m venv venv
source venv/bin/activate # or venv\Scripts\activate on Windows
pip install -e ".[dev]"
Or with uv (recommended):
git clone https://github.com/rdawebb/typer-extensions.git
cd typer-extensions
uv sync --all-extras
source .venv/bin/activate
Quick commands with justfile:
If you have just installed (included in [dev]), common tasks are available:
just test # Run tests
just lint # Run linter
just format # Format code
just type # Check type safety
just test-cov # Full test suite with coverage
just help # List all available commands
Testing
With justfile (recommended):
just check # Run linting, formatting, and type checks
just test # Run tests
just test-cov # Run tests with coverage report
just pre # Full pre-commit check (all checks + tests)
Or with direct commands:
pytest # Run all tests
pytest --cov # With coverage
pytest -v # Verbose output
ruff check . # Lint
ruff format . # Format
ty check src/ # Type check
Contributing
Contributions are welcome! Please open an issue, ask a question, or submit a pull request.
Project Status
Current Version: 0.4.0 (Beta)
✅ Core Features Complete:
- Alias registration (decorator + programmatic)
- Help text formatting
- Dynamic alias management
- Full test coverage
🚧 In Development:
- Dynamic config file loading with import/export
- Shell completion enhancement and typo suggestions
- Shared & chained subcommand aliases
- Performance optimisations
📋 Planned Features:
- Documentation site
- Per-alias help text
- Dataclass, Pydantic & Attrs support
- Custom themes and help text formatting
- Argument & Option customisation
Why typer-extensions?
For Users:
- ⚡ Faster workflows with short aliases
- 🎯 Familiar commands (git-like shortcuts)
- 📖 Clear help text showing all options
For Developers:
- 🧹 DRY - no code duplication
- 🔧 Flexible - static or dynamic aliases
- 🎨 Customisable - match your style
- ✅ Tested - reliable, stable, and type-safe
Compared to Alternatives:
- Plain Typer: Requires command duplication or hiding
- click-aliases: Click-specific, no Typer integration
- Custom solutions: Reinventing the wheel
Related Projects
- Typer - The CLI framework this extends
- Click - The underlying library
- Rich - Beautiful terminal formatting (used by Typer)
License
MIT License - see LICENSE file for details.
Acknowledgments
Built on the excellent Typer framework by Sebastián Ramírez.
Inspired by Git's command aliasing and various CLI tools that make shortcuts feel natural.
Support
- 🐛 Issues: GitHub Issues
- 💬 Discussions: GitHub Discussions
- 📧 Contact: Create an issue for questions
Links
- GitHub: https://github.com/rdawebb/typer-extensions
- PyPI: https://pypi.org/project/typer-extensions/
- Changelog: CHANGELOG.md
Metadata
Release files for typer-extensions 0.4.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| typer_extensions-0.4.0.tar.gz | 79.8 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| typer_extensions-0.4.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 107.0 kB
Release files / typer_extensions-0.4.0.tar.gz
| Download URL | typer_extensions-0.4.0.tar.gz |
|---|---|
| Size | 79.8 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
5bae3a5b368e4a60bba022221109f003b790d41b4a191d6a8856111a5bf2f643
|
|
BLAKE2b-256 checksum How to use checksums |
e61214b9bfb98a8d37e59d1386ca3ac66b3b2c971b8e26f616b7aaa6b1ed3966
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.12.13
|
Release files / typer_extensions-0.4.0-py3-none-any.whl
| Download URL | typer_extensions-0.4.0-py3-none-any.whl |
|---|---|
| Size | 27.2 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
66dbbb1130855e9f1e75b9c657b74018ceea707fbd2586fbf8245f2d88b8a017
|
|
BLAKE2b-256 checksum How to use checksums |
f971e824943b3022f88f544de0a965dde58a180a75cef130a1117047763a5a79
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.12.13
|