Hatch Cheat Sheet
Overview
Hatch is a modern, extensible Python project manager that handles the entire project lifecycle: building packages, managing environments, running tests, versioning, and publishing. It is PEP-compliant and uses pyproject.toml as its single configuration file, following modern Python packaging standards.
Hatch provides built-in support for environment management (replacing tox/virtualenv workflows), a powerful build backend (hatchling), version management, and project scaffolding. It emphasizes convention over configuration while remaining flexible for complex projects.
Installation
# Via pip
pip install hatch
# Via pipx (recommended)
pipx install hatch
# macOS
brew install hatch
# Verify
hatch --version
Core Commands
| Command | Description |
|---|---|
hatch new <name> | Create a new project |
hatch build | Build the package |
hatch publish | Publish to PyPI |
hatch env create | Create an environment |
hatch env show | Show environments |
hatch shell | Enter project environment shell |
hatch run <cmd> | Run command in default environment |
hatch run <env>:<cmd> | Run command in specific environment |
hatch test | Run tests |
hatch fmt | Format code |
hatch version | Show/set version |
hatch dep show | Show dependencies |
Project Setup
Create New Project
# Interactive creation
hatch new my-project
# With specific options
hatch new my-project --cli
# Initialize existing directory
hatch new --init
pyproject.toml Configuration
[build-system]
requires = ["hatchling"]
build-backend = "hatchling.build"
[project]
name = "my-project"
version = "0.1.0"
description = "A great Python project"
readme = "README.md"
requires-python = ">=3.9"
license = "MIT"
authors = [
{ name = "Your Name", email = "you@example.com" },
]
dependencies = [
"requests>=2.28",
"click>=8.0",
"pydantic>=2.0",
]
[project.optional-dependencies]
dev = [
"pytest>=7.0",
"pytest-cov",
"ruff",
"mypy",
]
[project.scripts]
my-cli = "my_project.cli:main"
[project.urls]
Homepage = "https://github.com/user/my-project"
Documentation = "https://my-project.readthedocs.io"
Environment Management
Default Environment
# Create default environment
hatch env create
# Enter shell
hatch shell
# Run command in environment
hatch run python -c "import my_project; print(my_project.__version__)"
hatch run pytest tests/
# Remove environment
hatch env remove
Custom Environments
# pyproject.toml
[tool.hatch.envs.default]
dependencies = [
"pytest",
"pytest-cov",
]
[tool.hatch.envs.default.scripts]
test = "pytest {args:tests}"
test-cov = "pytest --cov=src {args:tests}"
lint = "ruff check src/ tests/"
[tool.hatch.envs.docs]
dependencies = [
"mkdocs",
"mkdocs-material",
]
[tool.hatch.envs.docs.scripts]
build = "mkdocs build"
serve = "mkdocs serve"
[tool.hatch.envs.typing]
dependencies = [
"mypy",
"types-requests",
]
[tool.hatch.envs.typing.scripts]
check = "mypy src/"
# Run scripts
hatch run test
hatch run test-cov
hatch run docs:serve
hatch run typing:check
# Run across multiple Python versions
hatch run +py=3.10-3.12 test
Matrix Environments
[[tool.hatch.envs.test.matrix]]
python = ["3.10", "3.11", "3.12"]
[[tool.hatch.envs.test.matrix]]
python = ["3.12"]
django = ["4.2", "5.0"]
# Run tests across matrix
hatch run test:test
hatch run test.py3.12-django5.0:test
Building and Publishing
# Build sdist and wheel
hatch build
# Build specific format
hatch build -t sdist
hatch build -t wheel
# Clean build artifacts
hatch build --clean
# Publish to PyPI
hatch publish
# Publish to Test PyPI
hatch publish -r test
# Publish specific files
hatch publish dist/my_project-1.0.0-py3-none-any.whl
Configuration
Version Management
# Dynamic version from source
[tool.hatch.version]
path = "src/my_project/__about__.py"
# Or from VCS (git tags)
[tool.hatch.version]
source = "vcs"
[tool.hatch.build.hooks.vcs]
version-file = "src/my_project/_version.py"
# Show version
hatch version
# Set version
hatch version 1.2.0
# Bump version
hatch version minor # 1.1.0 -> 1.2.0
hatch version major # 1.2.0 -> 2.0.0
hatch version patch # 1.2.0 -> 1.2.1
hatch version dev # 1.2.0 -> 1.2.0.dev0
hatch version rc # 1.2.0 -> 1.2.0rc0
Build Configuration
[tool.hatch.build]
include = [
"src/my_project/",
]
exclude = [
"*.pyc",
"__pycache__/",
"tests/",
]
[tool.hatch.build.targets.sdist]
include = [
"/src",
"/tests",
"pyproject.toml",
]
[tool.hatch.build.targets.wheel]
packages = ["src/my_project"]
Advanced Usage
Hatch Config
# Show config location
hatch config find
# Show config
hatch config show
# Set default Python
hatch config set dirs.python default 3.12
# Set default shell
hatch config set shell bash
Formatting and Linting
# Format code (uses ruff)
hatch fmt
# Check without fixing
hatch fmt --check
# Lint only (no formatting)
hatch fmt --linter
# Configure formatter
[tool.hatch.format]
formatter = { }
[tool.ruff]
line-length = 88
[tool.ruff.format]
quote-style = "double"
Project Templates
# ~/.config/hatch/config.toml
[template]
name = "Your Name"
email = "you@example.com"
[template.licenses]
default = ["MIT"]
[template.plugins.default]
tests = true
ci = true
src-layout = true
Using with Pre-Commit
# .pre-commit-config.yaml
repos:
- repo: https://github.com/astral-sh/ruff-pre-commit
rev: v0.3.0
hooks:
- id: ruff
- id: ruff-format
Troubleshooting
| Issue | Solution |
|---|---|
| Environment creation fails | Check Python version; run hatch env prune |
| Build fails | Verify [build-system] in pyproject.toml |
| Version not updating | Check [tool.hatch.version] path configuration |
| Dependencies not found | Run hatch dep show to verify resolution |
| Script not found | Verify script is defined in correct environment |
| Publish auth fails | Set HATCH_INDEX_USER and HATCH_INDEX_AUTH |
# Verbose output
hatch -v run test
# Show all environments
hatch env show
# Prune all environments
hatch env prune
# Debug build
hatch build -v
# Show project info
hatch project metadata