# What is PEP 621?


[PEP 621](https://peps.python.org/pep-0621/) defines the `[project]` table in [pyproject.toml](https://pydevtools.com/handbook/reference/pyproject.toml.md) for declaring project name, version, description, dependencies, license, and other core metadata. Any compliant build tool can read this table without executing Python code or recognizing tool-specific configuration.

## How tools stored metadata before PEP 621

Before PEP 621, every build tool stored project metadata in its own format. [Setuptools](https://pydevtools.com/handbook/reference/setuptools.md) used `setup.py` (executable Python) or `setup.cfg` (an INI format with a setuptools-specific schema). [Flit](https://pydevtools.com/handbook/reference/flit.md) used `[tool.flit.metadata]`. [Poetry](https://pydevtools.com/handbook/reference/poetry.md) stored everything under `[tool.poetry]`.

Reading a project's name or dependencies required knowing which tool built it, or running its build system. Metadata inside `setup.py` could not be read statically at all.

## What the `[project]` table defines

PEP 621 reserves the `[project]` key in `pyproject.toml` for standard metadata. A minimal project configuration:

```toml
[project]
name = "my-package"
version = "1.0.0"
description = "A short description."
requires-python = ">=3.11"
dependencies = [
    "requests>=2.28",
]

[project.scripts]
my-tool = "my_package.cli:main"
```

`name` is always required. `version` is required unless listed in `dynamic` (see below). Optional fields include:

- `description`, `readme`, `requires-python`, `license`
- `authors`, `maintainers`, `keywords`, `classifiers`
- `urls`, `scripts`, `gui-scripts`, `entry-points`
- `dependencies`, `optional-dependencies`

These fields map directly to [core metadata](https://pydevtools.com/handbook/explanation/what-is-core-metadata.md), the wire format inside wheels and sdists. PEP 621 defines how the source-tree declaration translates into the same fields that installers read after a package is built.

## Computed fields: the `dynamic` key

Some projects derive their version from a git tag, a file, or a commit hash rather than hardcoding it in pyproject.toml. The `dynamic` key lists which fields the backend computes rather than reads from `[project]`:

```toml
[project]
name = "my-package"
dynamic = ["version"]
```

A plugin like `hatch-vcs` or `setuptools-scm` then supplies the version during the build. All other metadata still belongs in `[project]`.

## Which backends support PEP 621

| Backend | PEP 621 support |
|---|---|
| uv_build | Native |
| [Hatchling](https://pydevtools.com/handbook/reference/hatch.md) | Native |
| [flit_core](https://pydevtools.com/handbook/reference/flit.md) | Native (replaced `[tool.flit.metadata]`) |
| [setuptools](https://pydevtools.com/handbook/reference/setuptools.md) | From v61.0.0 |
| [pdm-backend](https://pydevtools.com/handbook/reference/pdm.md) | Native |
| [poetry-core](https://pydevtools.com/handbook/reference/poetry.md) | From Poetry 2.0; `[tool.poetry]` still works |

PEP 621 standardizes where metadata lives, not how packages get built. The `[build-system]` table from [PEP 517/518](https://pydevtools.com/handbook/explanation/what-is-pep-517.md) still determines which backend runs. Switching from Hatchling to uv_build means changing `[build-system]`; the `[project]` table stays the same.

## Related

- [What is PEP 517/518?](https://pydevtools.com/handbook/explanation/what-is-pep-517.md) covers the build-system interface that sits alongside the `[project]` table.
- [pyproject.toml reference](https://pydevtools.com/handbook/reference/pyproject.toml.md) documents every table the file supports, including `[project]`.
- [What is core metadata?](https://pydevtools.com/handbook/explanation/what-is-core-metadata.md) explains the wire format that `[project]` fields map to.
- [Why are there so many Python packaging tools?](https://pydevtools.com/handbook/explanation/why-are-there-so-many-python-packaging-tools.md) gives context for why this standardization was needed.

## Learn More

- [PEP 621 specification](https://peps.python.org/pep-0621/)
- [Python Packaging User Guide: pyproject.toml](https://packaging.python.org/en/latest/specifications/pyproject-toml/)
