What are Optional Dependencies and Dependency Groups?
Optional Dependencies: End-User Features
Optional dependencies, defined in pyproject.toml under [project.optional-dependencies] (part of the PEP 621 standard), are designed to:
- Package optional features that some users may want
- Allow users to install specific feature sets using the
pip install package[extra]syntax - Get published to PyPI along with the package
For example:
[project.optional-dependencies]
aws = [
"boto3>=1.26.0",
"s3fs>=2023.1.0",
]
visualization = [
"matplotlib>=3.7.0",
"seaborn>=0.12.0",
]This allows users to choose the features they need:
pip install mypackage[aws] # Only AWS-related features
pip install mypackage[visualization] # Only visualization featuresDependency Groups: Developer Tools
Dependency groups, defined under [dependency-groups], are meant for:
- Managing development-time dependencies
- Organizing tools needed for different development tasks
- Keeping the published package lean
A typical example might look like:
[dependency-groups]
test = [
"pytest>=7.0.0",
"coverage>=7.0.0",
]
lint = [
"ruff>=0.1.0",
"mypy>=1.0.0",
]These dependencies stay local to development and never get published to PyPI.
Choose between groups and extras
Ask yourself: will a user of the package need this dependency, or only a developer working on the package? If the answer is “user,” put it in [project.optional-dependencies]. If the answer is “developer,” put it in [dependency-groups].
Each optional dependency you expose becomes part of your public API, so keep the set small and stable.
Further Reading
- What is PEP 621? (storing project metadata in pyproject.toml)
- What is PEP 735? (dependency groups in pyproject.toml)
- Understanding Dependency Groups in uv
- Python Packaging User Guide - Declaring Dependencies