mono
A minimal Python CLI template
A production-ready template for building Python CLI tools with modern tooling, comprehensive testing, and CI/CD out of the box.
Quick Start
Install the example CLI:
Try it out:
mono hello
# Output: Hello, World!
mono hi Alice
# Output: Hi, Alice!
mono bye Bob
# Output: Goodbye, Bob!
Note
This example demonstrates the optional monorepo structure with three subpackages (mono-core, mono-one, mono-two). You can keep this structure or simplify to a single package.
Get Started โ View Usage โ
Features
This template provides:
- โจ Modern Python packaging with hatchling and hatch-vcs for automatic versioning
- ๐ฏ CLI framework using Typer with type hints and autocomplete support
- โ Code quality with Ruff for linting/formatting and mypy for type checking
- ๐งช Testing with pytest and coverage reporting
- ๐ช Pre-commit hooks configured and ready to use
- ๐ CI/CD with GitHub Actions (testing on multiple platforms/Python versions)
- ๐ Documentation infrastructure with Zensical
- ๐ฆ Automatic releases to PyPI when you tag versions
Why This Template?
This template embodies Python packaging best practices as of 2025:
pyproject.toml- Single source of truth for all configurationsrc/layout - Prevents accidental imports of uninstalled code- Type hints - Full type coverage with mypy
- Modern tools - Ruff (fast) instead of multiple slower tools
- Comprehensive CI - Test across platforms and Python versions
- Automatic versioning - Git tags become package versions
- Developer experience - Pre-commit hooks catch issues before CI
Using This Template
1. Create Your Repository
Click "Use this template" on GitHub or clone:
2. Customize the Package
Choose your structure:
Remove the example subpackages:
Update pyproject.toml to remove subpackage dependencies:
Keep the subpackages and customize them for your needs. Useful when you need to publish multiple packages separately.
Then, for either option:
Replace mono with your package name:
# macOS
find . -type f -not -path './.git/*' -exec sed -i '' 's/mono/yourpackage/g' {} +
# Linux
find . -type f -not -path './.git/*' -exec sed -i 's/mono/yourpackage/g' {} +
Rename directories:
mv src/mono src/yourpackage
# If keeping subpackages:
# mv mono-core yourpackage-core
# mv mono-one yourpackage-one
3. Start Building
Replace the example hello command in src/yourpackage/cli.py with your own commands.
See the Getting Started Guide for detailed instructions.
What's Included
Dependencies
Core:
- typer>=0.15 - CLI framework with rich features
Development:
- pytest>=8, pytest-cov>=4 - Testing and coverage
- mypy>=1.14 - Static type checker
- ruff>=0.9 - Fast linter and formatter
- pre-commit>=4 - Git hook framework
Documentation:
- zensical - Documentation builder
- markdown-gfm-admonition - Enhanced markdown
CI/CD Workflows
- pytest.yml - Runs tests on Python 3.12+ across Linux, macOS, and Windows
- release.yml - Publishes to PyPI when you tag a version
- docs.yml - Builds and deploys documentation to GitHub Pages
Project Structure
This template supports two project structures:
.
โโโ .github/workflows/ # CI/CD workflows
โโโ docs/ # Documentation source
โโโ src/yourpackage/ # Your package code
โ โโโ __init__.py
โ โโโ cli.py
โโโ tests/ # Test files
โโโ pyproject.toml # Package metadata
โโโ zensical.toml # Docs configuration
.
โโโ .github/workflows/
โโโ docs/
โโโ yourpackage-core/ # Separate subpackage
โ โโโ pyproject.toml
โ โโโ README.md
โ โโโ src/yourpackage_core/
โโโ yourpackage-one/ # Another subpackage
โ โโโ pyproject.toml
โ โโโ README.md
โ โโโ src/yourpackage_one/
โโโ src/yourpackage/ # Main CLI package
โ โโโ __init__.py
โ โโโ cli.py
โโโ tests/
โโโ pyproject.toml # Main project config
โโโ zensical.toml
When to use the monorepo structure:
- You need to publish multiple packages separately to PyPI
- Different parts have different dependencies
- You want independent versioning for subpackages
- You're building a plugin ecosystem or modular toolkit
License
MIT - feel free to use this template for any project.