Migrate setup.py to pyproject.toml
Modern Python packaging is declarative in pyproject.toml. Move project metadata into the [project] table, declare a build backend under [build-system], and keep installs working with pip install -e .
Pattern modernizationDifficulty: moderateEffort: 2 hours to 1 daylow risk
Last verified · Updated May 22, 2026
PEP 517/518/621 made pyproject.toml the standard for Python packaging. Declare your build backend under [build-system], move metadata into the [project] table, and verify with an editable install — no executable setup.py required.
Transformation rules
| setup.py | pyproject.toml |
|---|---|
| setup(name=, version=) | [project] name / version |
| install_requires | [project] dependencies |
| extras_require | [project.optional-dependencies] |
| entry_points | [project.scripts] / [project.entry-points] |
| setup_requires / build deps | [build-system] requires |
Minimal pyproject.toml with the setuptools backend
[build-system]
requires = ["setuptools>=61"]
build-backend = "setuptools.build_meta"
[project]
name = "example"
version = "1.0.0"
requires-python = ">=3.12"
dependencies = ["requests>=2.31"]
[project.scripts]
example = "example.cli:main"Choosing a build backend
- setuptools — closest to legacy setup.py; lowest-friction migration.
- hatchling — modern, fast, sensible defaults for new projects.
- poetry-core — if you already manage dependencies with Poetry.
When the pattern applies
- Any project still shipping an executable setup.py for metadata.
- Packages adopting PEP 621 metadata or a new build backend.
Verification
Editable install plus a wheel/sdist build
# Verify the declarative build works
python -m pip install -e .
python -m buildEdge cases
- Dynamic metadata (e.g. version from VCS) needs [tool] backend config or dynamic = [...].
- C extensions still require a build backend that compiles them (keep setuptools).
- Custom setup.py logic should move to backend hooks, not be ported verbatim.
Related paths
- Python 2 to Python 3 Migration Guide — Related path
- Python 3.8 to 3.12 Migration Guide — Related path
- Upgrade to Python 3 — Next step forward
- Fix Python Dependency Errors — Next step forward
Official sources
- Python Packaging User Guide — packaging.python.org (reliability 98%)
- Writing your pyproject.toml — packaging.python.org (reliability 98%)