requirements.txt lists packages for an environment; pyproject.toml declares project metadata and build config
requirements.txt is a plain text list of packages, optionally with version specifiers and hashes, consumed by pip. It is simple and widely understood but has no standard place for project metadata, build system configuration, optional extras, or entry points. pyproject.toml, introduced by PEP 518 and extended by PEP 621, is the modern standard for declaring a project's build backend, metadata such as name and version, dependencies, optional dependency groups, and tool configuration. Pip can install from pyproject.toml when a build backend such as setuptools, hatchling, poetry-core, or flit is declared. Libraries should prefer pyproject.toml because it defines a proper installable package. Applications often still use requirements.txt or a lock file for deployment, because it captures the exact resolved versions of the full dependency tree. The pragmatic pattern is pyproject.toml for the project definition and a generated lock file for reproducible installs.
requirements.txt: flat list, easy to use, no build backend or metadata. Good for simple deployments and lock snapshots.
pyproject.toml: build-system, project metadata, dependencies, optional extras, entry points, and tool config in one file.
PEP 517 defines the build backend interface; PEP 518 defines pyproject.toml; PEP 621 defines the [project] table.
Tools: poetry, pdm, hatch, and flit all use pyproject.toml and add lock files.
Trade-off: pyproject.toml is richer but requires a build backend and a tool that understands it. requirements.txt works with everything and is trivial to audit.
Common mistake: keeping setup.py only and no pyproject.toml, which limits modern tooling and build reproducibility.
Common mistake: hand-editing requirements.txt and losing the distinction between direct dependencies and transitive ones.
Version note: PEP 621 support is available in setuptools 61+, poetry 1.2+, and most modern tools. Older tooling may require setup.cfg or setup.py.
0-2 years experience
2-5 years experience
5-8 years experience
8+ years experience