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.
The Key Difference
Optional dependencies get published to PyPI and let end users opt into additional features. Dependency groups stay local to development and never ship with the package.
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].
Choosing Between Them
Use optional dependencies for capabilities that extend what your package does for its users, like database drivers or file-format support. Use dependency groups for tooling that supports the development process itself, like linters and test runners. Each optional dependency you expose becomes part of your public API, so keep the set small and stable.
Note
Dependency groups are a relatively new addition to the Python packaging ecosystem, introduced in PEP 735. They may not be supported in all tools.
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