# Why Should I Choose pyproject.toml over requirements.txt for managing dependencies?

[requirements.txt](https://pydevtools.com/handbook/reference/requirements.md) lists packages to install. [pyproject.toml](https://pydevtools.com/handbook/reference/pyproject.toml.md) defines a project. That distinction shapes how dependencies get managed and how projects scale.

## What requirements.txt does well

The format is plain text, one package per line:

```text
requests>=2.28.0
pandas~=2.0.0
```

Any tool that speaks pip can consume it. Files can be hosted online and installed via URL (`pip install -r https://example.com/requirements.txt`). For scripts or one-off environments, that simplicity is hard to beat.

## Where requirements.txt falls short

The workflow around requirements.txt demands manual coordination. A developer creates a virtual environment, activates it, installs packages with pip, then remembers to update the file by hand. Each step is a chance for the file and the environment to drift apart.

The format also has structural gaps:

- No Python version constraint. Nothing stops installation into an incompatible interpreter.
- No dev/prod separation. Splitting dependencies requires multiple files (requirements-dev.txt, requirements-test.txt) with no standard convention.
- No project metadata. Name, version, authors, and build configuration live elsewhere (setup.py, setup.cfg), spreading a project's identity across files.

## What pyproject.toml changes

[PEP 621](https://peps.python.org/pep-0621/) standardized project metadata in pyproject.toml. Dependencies, Python version constraints, project metadata, and tool configuration all live in one file. Tools like [flit](https://pydevtools.com/handbook/reference/flit.md), [hatch](https://pydevtools.com/handbook/reference/hatch.md), [pdm](https://pydevtools.com/handbook/reference/pdm.md), [poetry](https://pydevtools.com/handbook/reference/poetry.md), and [uv](https://pydevtools.com/handbook/reference/uv.md) all support it.

The difference becomes concrete when you set up a new project. With requirements.txt, you perform each step yourself:

```bash
mkdir myproject && cd myproject
python -m venv .venv
```

```bash
source .venv/bin/activate
```
```bash
.venv\Scripts\activate
```
```bash
pip install requests pandas
# now manually add them to requirements.txt
```

With [uv](https://pydevtools.com/handbook/reference/uv.md):

```bash
uv init myproject && cd myproject
uv add requests pandas
```

`uv init` creates the project and its virtual environment. `uv add` installs packages and records them in pyproject.toml in one step. No activation, no manual bookkeeping. When another developer clones the repo, `uv sync` reproduces the environment from the lockfile.

> [!TIP]
> The .venv directory that uv creates works like any standard virtual environment. Activate it manually when an IDE or tool requires it.

## One file for the whole project

pyproject.toml replaces the constellation of setup.py, setup.cfg, [tox](https://pydevtools.com/handbook/reference/tox.md).ini, and requirements files with a single source of truth. The same file works whether the project is an application or a distributable package. Dev dependencies and [dependency groups](https://pydevtools.com/handbook/explanation/what-are-optional-dependencies-and-dependency-groups.md) live alongside production dependencies, governed by a standard rather than ad-hoc file naming.

## Which to use

Use pyproject.toml for new projects. For existing projects still on requirements.txt, see [How to migrate from requirements.txt to pyproject.toml with uv](https://pydevtools.com/handbook/how-to/migrate-requirements.txt.md).

## Related

- [pyproject.toml reference](https://pydevtools.com/handbook/reference/pyproject.toml.md) covers the full specification
- [requirements.txt reference](https://pydevtools.com/handbook/reference/requirements.md) documents the traditional format
- [What are Optional Dependencies and Dependency Groups?](https://pydevtools.com/handbook/explanation/what-are-optional-dependencies-and-dependency-groups.md) explains how pyproject.toml handles dev dependencies
- [Create your first Python project](https://pydevtools.com/handbook/tutorial/create-your-first-python-project.md) walks through starting a new uv project from scratch
- [What is a lockfile?](https://pydevtools.com/handbook/explanation/what-is-a-lock-file.md) explains the reproducibility benefits of uv's lockfile
