Pick the simplest backend that handles your needs. For pure Python code, any standards compliant backend works, so choose by how it computes versions and includes files. If you build C extensions, you need a backend that supports them. Whatever you choose, copy its exact settings from its own docs.
What the backend actually does
A build backend is the library behind python -m build that turns your source tree into a source distribution and a wheel. Frontends like pip and build do not convert sources themselves. The Python Packaging User Guide lists several common backends in its tutorial: hatchling, setuptools, flit-core, PDM's backend and uv-build. Poetry's core library is another option.
All of them read the [build-system] table, and most read the standard [project] table for metadata. A notable exception was Poetry before version 2.0, released on January 5, 2025, which used its own [tool.poetry] table. From 2.0 it supports both.
Decision guide
Answer these in order. Stop at the first row that applies.
| Question | If yes | Why |
|---|---|---|
| Do you ship compiled extensions (C, C++, Rust, Cython)? | Choose a backend that documents extension support | The guide notes backends differ on whether they support building extension modules |
| Do you need the version taken from Git tags? | Choose a backend with a version source plugin or built in support | Keeps tag and artifact in sync |
| Is it a small pure Python library with a hand written version? | A minimal backend is enough | Fewer moving parts |
| Do you need programmatic build logic? | A backend that supports a Python build script | The guide says to keep setup.py only when programmatic configuration is needed |
| Are you migrating an old project? | Keep your current backend first | Change one thing at a time |
Features worth checking before you commit
- PEP 639 license support. The guide lists the first backend versions that read the license expression and license-files fields, so check that your pinned minimum is at or above that version. If a build fails saying license should be a table, your backend is too old for the new format.
- Static metadata by default. Prefer a backend that lets you write version and dependencies directly, and uses dynamic fields only where needed.
- Predictable sdist contents. The sdist specification defines almost nothing about what else goes in the archive, so each backend has its own include and exclude rules. Read them.
- Maintenance signals. Release cadence, open issues and who maintains the backend matter, because it runs at build time for you and for anyone installing from source.
What not to do
Do not switch backends mid release cycle without comparing the built artifacts. Build an sdist and wheel with the old backend, build again with the new one, and diff the file lists. Do not assume python setup.py commands are the way to build. The guide says calling setup.py as a command is deprecated, though setuptools itself is not.
A safe way to try one
- Create a clean virtual environment.
- Set
[build-system]using the pair from the backend's docs. - Run
python -m build. - List the wheel with
unzip -land the sdist withtar tzf. - Install the wheel into a second clean environment and import your package.
Safeguard's SBOM and dependency scanning can show what your library pulls in once built. You can try a free scan on a project.
Quick check
Does the build backend affect users of my library?
Indirectly. Users who install a wheel never run it. Users who install from the sdist run your backend and everything in requires, so it affects them too.
Can I change backends later?
Yes, because the build interface is standardized. Compare the file lists of artifacts built both ways before you release.
Is setuptools deprecated?
No. The guide says setuptools is a fine backend. What is deprecated is running setup.py as a command line tool.
Sources
- Packaging Python Projects, Python Packaging User Guide
- Writing your pyproject.toml, Python Packaging User Guide
- Is setup.py deprecated?, Python Packaging User Guide
- Source distribution format, Python Packaging User Guide
Last reviewed: 19 October 2026.