Rishabh Singh
HomeAboutServicesProjectsOpen SourceBlogVisitorsContact

v2025 · Next.js + Tailwind

All Posts
Home/Blog/requirements.txt in Python
Read on Medium
Pythonpip

requirements.txt in Python

Two commands every Python developer needs: pip freeze captures your environment, pip install -r recreates it anywhere.

August 24, 20225 min readRishabh Singh
requirements.txt file showing Python package versions
A requirements.txt file pins every dependency to an exact version — making environments reproducible.

requirements.txt is a plain text file that lists a Python project's dependencies — one package per line, usually pinned to an exact version — so the environment can be recreated identically on any machine. The workflow is two commands: pip freeze > requirements.txt captures every package installed in the active virtual environment with its exact version, and pip install -r requirements.txt reinstalls that exact set anywhere else. This is what makes a project portable: without pinned versions, a collaborator or a cloud platform installs whatever is latest today, which may rename APIs, change defaults, or break behavior your code depends on. The file supports exact pins (==), minimum versions (>=), compatible releases (~=), comments, and extras, and it belongs in version control next to your code.

The Problem

Three situations where version mismatches kill projects:

  • Legacy projects: code written with an older scikit-learn uses an API that was renamed or removed in the version you have installed
  • Collaboration: your colleague's environment has TensorFlow 2.12 while yours has 2.15 — different behavior, different errors
  • Cloud deployment: your app works locally but breaks on AWS, Azure, or GCP because the platform installs the latest version, not the one you developed with
"Good developers take time to maintain good projects — and that means pinning dependencies so the project works the same everywhere."

The Solution: requirements.txt

requirements.txt is a plain text file that lists every package name and its exact version number. Anyone can recreate your exact environment from this one file.

pip freeze command output showing package versions
pip freeze outputs every installed package and its version — redirect it to a file to capture your environment.

Command 1: Create requirements.txt

Activate your virtual environment first, then run:

pip freeze > requirements.txt

This captures every installed package and its exact version into the file. Always run inside an activated virtual environment — otherwise you'll capture system-level packages too.

Command 2: Install from requirements.txt

pip install -r requirements.txt
pip install -r requirements.txt installing packages
pip install -r requirements.txt recreates the exact environment on any machine.

The -r flag tells pip to read requirements from a file. Every package is installed at the exact pinned version — same result on any machine, any cloud platform.

What Can You Write in a requirements.txt File?

The file isn't limited to package==version lines. Pip's requirement syntax supports comments, version ranges, extras, and even including other requirement files:

# exact pin — fully reproducible
numpy==1.26.4

# compatible release — allows 2.2.x patch updates, blocks 2.3
pandas~=2.2.0

# minimum version — anything newer is accepted
requests>=2.31

# extras — install optional dependency groups
uvicorn[standard]==0.29.0

# include another requirements file
-r requirements-base.txt

The specifiers do different jobs. == is for reproducibility — deployments and CI should get exactly what you tested. ~= (compatible release) accepts bug-fix updates while blocking breaking ones. >= is the loosest and belongs in library metadata more than application requirements — an unbounded range that resolves differently every month is how "works on my machine" bugs are born.

A common project convention is two files: requirements.txt for runtime dependencies and requirements-dev.txt that starts with -r requirements.txt and adds test and lint tools (pytest, ruff) on top.

When Is pip freeze Not Enough?

pip freeze has one blind spot: it flattens everything. Your project may directly use five packages, but freeze outputs fifty — the five plus all their transitive dependencies — with no record of which is which. Six months later, nobody remembers whether idna is something you chose or something requests dragged in. Tools like pip-tools fix this by separating intent from result: you hand-write a short requirements.in with just your direct dependencies, and pip-compile generates the fully pinned requirements.txt, annotating every transitive package with the reason it's there.

Aspectpip freezepip-tools (pip-compile)
InputWhatever is installed in the environmentHand-written requirements.in of direct deps
Direct vs transitiveIndistinguishable — one flat listTransitive deps annotated with their source
Stray packagesCaptured (including one-off experiments)Excluded — only what resolves from your inputs
Upgrading one packageManual edit, hope nothing conflictspip-compile --upgrade-package name re-resolves safely
Setup costZero — built into pipOne extra tool to install and learn

For small projects and notebooks, pip freeze is perfectly fine. For anything long-lived or deployed, compiled pins pay for themselves — the same philosophy behind Poetry and uv lockfiles, and behind pyproject.toml dependencies in modern packaging. Conda users get the equivalent reproducibility from conda env export and environment.yml.

How Do You Keep requirements.txt Up to Date?

A pinned file drifts out of date by design — that's the point — so updating is a deliberate act, not an accident:

# see what has newer releases
pip list --outdated

# upgrade one package deliberately
pip install --upgrade pandas

# re-capture the environment
pip freeze > requirements.txt

Upgrade, run your tests, then regenerate and commit the file in the same change. The commit history of requirements.txt becomes an audit log of every dependency change the project has ever made — which is exactly what you want when a deploy suddenly misbehaves.

Video Tutorial

Best Practices

  • Always work in a virtual environment — pip freeze from a global environment captures hundreds of unrelated packages
  • Commit requirements.txt to version control — it belongs in your repo alongside your code
  • Regenerate after adding packages — run pip freeze > requirements.txt every time you install a new dependency
  • For production: consider pinning transitive dependencies with pip-compile from pip-tools for fully reproducible builds
Back to BlogRead on Medium

© 2026 Rishabh Singh · Data Scientist & AI Engineer

PrivacyGitHubLinkedInMedium