This project has been archived by its maintainers, and is no longer receiving any updates.
typer-aliases
Command aliases for Typer CLI applications with grouped help text display
Overview
typer-aliases extends Typer to provide first-class 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
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-aliases:
from typer_aliases import AliasedTyper
app = AliasedTyper()
@app.command_with_aliases("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 listapp lsapp l
Features
✨ Decorator-based alias registration - Clean, intuitive syntax
🔧 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 your shell completion setup
🧪 Well-tested - Tested on Python 3.9-3.14 with 100% test coverage
Installation
pip install typer-aliases
Requirements:
- Python 3.9+
- typer >= 0.9.0 (recommend installing the latest version)
- click >= 8.0.0
Quick Start
Basic Usage
from typer_aliases import AliasedTyper
app = AliasedTyper()
@app.command_with_aliases("list", aliases=["ls", "l"])
def list_items():
"""List all items."""
print("Listing items...")
@app.command_with_aliases("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
💡 Want to learn more? Check the API Reference for detailed configuration options, or see the User Guide for patterns and best practices.
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-aliases)
from typer_aliases import AliasedTyper
app = AliasedTyper()
# That's it! Everything else stays the same.
# Your 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_with_aliases(), or to existing commands using the programmatic API.
See Migration Guide for detailed migration strategies and patterns.
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 = AliasedTyper(
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
Run any example:
python examples/basic_usage.py --help
python examples/basic_usage.py ls
Real-World Use Cases
Git-like CLI
@app.command_with_aliases("checkout", aliases=["co"])
def checkout(branch: str):
"""Switch branches."""
...
@app.command_with_aliases("status", aliases=["st"])
def status():
"""Show status."""
...
Package Manager
@app.command_with_aliases("install", aliases=["i", "add"])
def install(package: str):
"""Install a package."""
...
@app.command_with_aliases("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_with_aliases(name, aliases=[...])
Programmatic Registration
app.add_aliased_command(func, name, aliases=[...])
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
AliasedTyper(
alias_case_sensitive=None, # Case-sensitive matching (default True per 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-aliases.git
cd typer-aliases
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-aliases.git
cd typer-aliases
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
If you prefer to use just without the dev setup, you can install it globally via pip install rust-just or your system package manager.
See Justfile for 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.2.0 (Beta)
✅ Core Features Complete:
- Alias registration (decorator + programmatic)
- Help text formatting
- Dynamic alias management
- Full test coverage
🚧 In Development:
- Documentation site
- Additional examples
- Performance optimisations
📋 Planned Features:
- Dynamic config file loading with import/export
- Shell completion enhancements
- Per-alias help text
See CHANGELOG.md for version history.
Why typer-aliases?
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-aliases
- PyPI: https://pypi.org/project/typer-aliases/
- Changelog: CHANGELOG.md
Making CLI aliases natural and maintainable
Metadata
Release files for typer-aliases 0.2.1
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_aliases-0.2.1.tar.gz | 31.7 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| typer_aliases-0.2.1-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 44.1 kB
Release files / typer_aliases-0.2.1.tar.gz
| Download URL | typer_aliases-0.2.1.tar.gz |
|---|---|
| Size | 31.7 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
7f7ac7d8c782be1a578bd6066fe7df0a3009821b7c39bc502709eb8fb7003158
|
|
BLAKE2b-256 checksum How to use checksums |
02fdbef849b1e0599294f55b9bae97fefc85999384517dcd40bdf341de43a700
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.14.2
|
Release files / typer_aliases-0.2.1-py3-none-any.whl
| Download URL | typer_aliases-0.2.1-py3-none-any.whl |
|---|---|
| Size | 12.4 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
32b69ee5115b4ae5d9db4c9aff59e4c0207c4a3ddd067d33d78374a38667e549
|
|
BLAKE2b-256 checksum How to use checksums |
19435557c7d1709b9926e6a06a7ee73634e0637a159322b345f3a64dcb472b7a
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.14.2
|