# requirements.txt: Python Dependency File Format


A plain-text file format for declaring Python package dependencies. Each line specifies a package and optional version constraint. The file is consumed by [pip](https://pydevtools.com/handbook/reference/pip.md), [uv](https://pydevtools.com/handbook/reference/uv.md), and other installers, typically via `pip install -r requirements.txt`. The filename is a convention, not a requirement — any text file works.

> [!NOTE]
> For new projects, declaring dependencies in [pyproject.toml](https://pydevtools.com/handbook/reference/pyproject.toml.md) and managing them with [uv](https://pydevtools.com/handbook/reference/uv.md) is the recommended approach. requirements.txt remains relevant as a deployment artifact and in legacy codebases.

## Syntax

Each non-blank, non-comment line is a [requirement specifier](https://pip.pypa.io/en/stable/reference/requirement-specifiers/). Comments begin with `#`.

```txt
# Pin to an exact version
numpy==1.24.1

# Set a minimum version
requests>=2.28.0

# Compatible release (>=2.0, <3.0)
pandas~=2.0

# No version constraint
flask

# Environment markers
pywin32; sys_platform == 'win32'
```

The format also supports options that control installer behavior:

```txt
# Include dependencies from another file
-r base-requirements.txt

# Install a local package in editable mode
-e .

# Use a custom package index
--index-url https://pypi.example.com/simple/
```

## Common Patterns

A hand-written requirements.txt declares direct dependencies with flexible version ranges:

```txt
# requirements.txt
requests>=2.28
pandas~=2.0
sqlalchemy>=2.0,<3.0
```

A pinned requirements.txt (generated by `pip freeze`, [pip-tools](https://pydevtools.com/handbook/reference/pip-tools.md), or [uv](https://pydevtools.com/handbook/reference/uv.md)) locks every package — including transitive dependencies — to exact versions:

```txt
# requirements.txt (pinned)
certifi==2024.2.2
charset-normalizer==3.3.2
idna==3.7
numpy==1.26.4
pandas==2.2.1
python-dateutil==2.9.0
pytz==2024.1
requests==2.31.0
six==1.16.0
sqlalchemy==2.0.29
tzdata==2024.1
urllib3==2.2.1
```

The hand-written file is easier to maintain. The pinned file produces reproducible installs. Most workflows use both: a loose file for authoring and a pinned file for deployment.

## Limitations

- No Python version specification. The file cannot declare which Python versions the project supports; that metadata belongs in [pyproject.toml](https://pydevtools.com/handbook/reference/pyproject.toml.md).
- No dependency groups. There is no built-in mechanism to separate production from development dependencies. The common workaround is maintaining multiple files (`requirements.txt`, `requirements-dev.txt`), which adds overhead.
- Not reproducible by default. Without pinning every transitive dependency, installs can differ between machines and over time. Tools like [pip-tools](https://pydevtools.com/handbook/reference/pip-tools.md) and [uv](https://pydevtools.com/handbook/reference/uv.md) solve this by generating fully pinned output.
- No project metadata. The file carries no information about the project itself — no name, version, or description. It is a dependency list, not a project definition.
- Being superseded. [PEP 621](https://peps.python.org/pep-0621/) established [pyproject.toml](https://pydevtools.com/handbook/reference/pyproject.toml.md) as the standard place to declare dependencies alongside project metadata. Most modern tools support it natively.

## Learn More

- [requirements.txt file format documentation](https://pip.pypa.io/en/stable/reference/requirements-file-format/)
- [Install packages in a virtual environment using pip and venv](https://packaging.python.org/en/latest/guides/installing-using-pip-and-virtual-environments/#creating-a-virtual-environment)
