requirements.txt: the dependency list of a Python project

requirements.txt lists the libraries a Python project needs, so that pip can rebuild the whole environment with a single command.
5 min read
Believemy logo

Definition

You pick up a Python project you have never installed before, and nothing works on the first run: some libraries are missing, and nothing on screen says which ones. requirements.txt answers that exact annoyance by listing, one per line, what the project needs. It holds no code and Python never reads it itself: pip turned it into a de facto standard just by agreeing to open it, with no PEP ever defining it officially.

A blank line does not count, and neither does a line starting with a hash, which leaves room for a comment above each group. An example makes it obvious.

BASH
# Application dependencies
requests==2.32.3
flask==3.0.3
pandas==2.2.2

A single command then rebuilds the entire environment, fetching every package from PyPI.

BASH
pip install -r requirements.txt
Good to know

The name written in the file is the package's name on PyPI, not the name you later import: you run pip install Pillow but write import PIL.


The problem it solves

A Git repository keeps the code, never the libraries it uses. Whoever clones the project therefore gets files calling tools missing from their machine.

PYTHON
import requests
import pandas as pd
from flask import Flask

# Three libraries, none of them installed on a fresh machine

With no written list, you run the program, read the error, install the named library, run again, and start over for every orphan import line. With three libraries that is manageable; with the thirty a real application uses, it becomes a lost afternoon, one every new developer loses again on their first day. The file replaces that hunt with a single command: the server installs the same list the development machine had, and "it works on my machine" stops being an acceptable explanation.


Pinning versions, or not

The same library, written three different ways, will not produce the same installation six months later. Here is what each writing means for pip.

WritingWhat pip installsWhen to choose it
flaskThe latest published version, whatever it isNever on a deployed project
flask>=3.0Any version from 3.0 upwardsFor a library others will install
flask==3.0.3That exact version, and no otherFor an application going live

An application lives alone on its server: it has nothing to negotiate and can pin the exact version that was tested. A library, on the other hand, will sit alongside others, chosen by someone else: demanding an exact version of each of its own dependencies would collide with the first other library in the project asking for a different one. So it loosens its constraints instead, and leaves the application to decide.


pip freeze, and the trap that comes with it

Writing a file of several dozen lines by hand would be tedious, so pip offers to do it for you.

BASH
pip freeze > requirements.txt

This command copies out everything installed in the current environment: with no virtual environment active, it also grabs tools from other projects, turning three real dependencies into a hundred and fifty lines. The fix is to create a venv per project before installing anything, not to clean the file by hand.

A second effect is quieter: pip freeze mixes chosen libraries with the ones they brought along as indirect dependencies. Nothing then tells one apart from the other, and removing a library later turns into archaeology.

Warning

Installing a library with pip install does not update requirements.txt on its own: the project keeps working locally until the first deployment, where the import fails because the file was never completed before committing it.


requirements.txt or pyproject.toml

The latter is the official format for describing a Python project, and it is tempting to present it as the natural successor to the former. The truth deserves to be more nuanced.

Criterionrequirements.txtpyproject.toml
RoleList what must be installedDescribe the project and its dependencies
Indirect dependenciesMixed in with the restKept apart, frozen by a lock file
Toolingpip is enoughA dedicated manager, such as poetry
Publishing a libraryOut of reachThat is its primary use

The newer format does not make the older one obsolete, it answers a different need: plenty of hosting providers and Docker images still look for a requirements.txt and nothing else. A personal script is well served by the plain text file; a team wanting bit-for-bit identical installs needs the lock file.


What it does not do

Three reasonable expectations run into the limits of the format.

The first concerns the Python version itself: the file says nothing anywhere about which version the project needs, and a pinned requirements.txt will still install without complaint on an interpreter that is far too old, before the program breaks further along, on a syntax it does not recognise.

The second concerns the virtual environment. The file does not create it, it assumes one is already active, which explains most installations that ended up in the system Python by mistake.

The third concerns whatever is not Python at all: a dependency that quietly needs a compiler or a database client will fail on a bare machine. These limits are the price of its simplicity.


Frequently asked questions

Question

Should requirements.txt be committed to the repository?

Yes, that is its whole reason to exist: it travels with the code and stays readable by whoever clones the project. What should never follow it is the virtual environment folder, heavy and valid only on the machine that created it.

Question

Why does the installation fail when the file has not changed?

Because an indirect dependency was not pinned, and published an incompatible version in the meantime. The file itself did not change, but what it points at shifted under it: that is the central argument for a frozen list on anything going to production.

Question

How can development tools be kept apart from real dependencies?

By writing a second file, requirements-dev.txt, whose first line pulls in the first one via the -r option, before adding pytest or ruff. The server then installs only the production list.

Related terms

Discover our python glossary

Browse the terms and definitions most commonly used in development with Python.

Share this article

Want to help us? Share this article on your networks or even better: on your site, in an article or in your newsletter.