All Articles
Concept·5 min read

Python Packaging in 2026: pyproject.toml, Explained

setup.py, requirements.txt, setup.cfg — the old sprawl has collapsed into one file. Here is what pyproject.toml is and why it won.

Part of: Python Programming & Development

If you learned Python a few years ago, packaging meant a confusing pile: setup.py, setup.cfg, requirements.txt, MANIFEST.in. Today one file replaces most of that — pyproject.toml. Here is what it is and why it exists.

The Problem It Solves

The old setup.py was a Python script that ran to describe your package. That created a chicken-and-egg problem: tools had to execute arbitrary code just to learn what your package needed. It was also non-standard — every tool invented its own config format.

pyproject.toml is declarative data, not code. Any tool can read it without running anything.

The Three Sections That Matter

[build-system] tells installers how to build your package. This is the part that ended the chicken-and-egg problem:

[build-system] requires = ["hatchling"] build-backend = "hatchling.build"

[project] is the standardized metadata — name, version, dependencies. This replaced setup.py's arguments:

[project] name = "myapp" version = "1.2.0" requires-python = ">=3.11" dependencies = [ "httpx>=0.27", "pydantic>=2.0", ]

[tool.*] is where individual tools keep their config, so they stop needing separate files:

[tool.ruff] line-length = 100 [tool.mypy] strict = true

Where requirements.txt Fits Now

dependencies in [project] lists the abstract requirements of your package ("needs httpx 0.27+"). A lock file — produced by tools like uv or pip-tools — pins the exact versions for reproducible installs. You still have both, but the roles are now clear: pyproject.toml declares, the lock file freezes.

Why It Won

  • ▸One standard file every tool understands.
  • ▸Declarative, so no code execution to read metadata.
  • ▸Absorbs tool config, killing the setup.cfg/MANIFEST.in sprawl.

Summary

pyproject.toml is the single, standardized home for your project's build instructions, metadata, and tool settings. Learn its three core tables — [build-system], [project], and [tool.*] — and the historical packaging confusion mostly disappears.

#Python#Packaging#pyproject#Tooling

Want to go deeper?

Python Programming & Development

View Course