Safeguard
Developer Tools•

pip constraints files vs requirements files: what is the difference

A requirements file says what to install. A constraints file only limits which versions may be chosen. See when each helps and how to combine them.

Safeguard Security Team
3 min read

A requirements file lists packages pip should install. A constraints file, passed with the c flag, only limits which versions pip may pick, and it never causes anything to be installed. That makes constraints a good way to pin transitive dependencies without adding them to your project.

The definitions

The pip documentation says constraints files are requirements files that only control which version of a requirement is installed. Including a package in a constraints file does not trigger installation of that package.

Usage looks like this.

python -m pip install -r requirements.txt -c constraints.txt

Restrictions from the docs: each constraint must name a package, cannot be editable, and cannot specify extras. They use a subset of requirements file syntax.

Constraints do not override existing requirements. They narrow which versions the resolver may consider.

Pinning with pip freeze

The simplest repeatable setup is a frozen requirements file. The docs describe it: the file holds a pinned version of everything that was installed when you ran pip freeze.

python -m pip freeze > requirements.txt
python -m pip install -r requirements.txt

That pins direct and transitive packages alike, but it mixes them in one flat list, so you lose the record of what you asked for versus what came along.

Where constraints help

Separate intent from resolution. Keep a short requirements file of what your application needs, and a constraints file of exact versions for the whole tree. The first is readable. The second is generated.

Share a baseline across projects. Several services can use one constraints file so they share versions of common libraries.

Pin a transitive package. If an advisory affects a package you do not depend on directly, add a constraint for the fixed version. If something in the tree needs the package, it will be installed at your version. If nothing does, nothing is installed.

Reuse across environments. The same constraints file can serve development, test and production installs.

Things to watch

  • A constraint that conflicts with what a package needs makes the resolver fail. That is useful signal, not an error to silence.
  • Hash checking mode requires every requirement to be an exact version match, and the docs say it may not work well with constraints. If you need hashes, see pip hash checking.
  • A separate build constraint option applies only to isolated build environments. The docs say regular constraints files no longer affect those environments as of pip 26.2.
  • Constraints rot. A file generated once and never refreshed pins you to old versions.

A simple setup

  1. Write requirements.txt with the packages you chose.
  2. Generate a fully pinned file with a compile tool, or with pip freeze from a clean environment.
  3. Commit both. Install with the requirements file and the constraints file in CI.
  4. Refresh on a schedule, and review the diff.

Safeguard's dependency scanning checks Python packages for known issues, and a free scan is at gold.safeguard.sh/scan.

Quick check

Does a constraint install the package?

No. A constraints file only limits the versions pip may choose when a package is needed.

Can I use extras in a constraints file?

No. Constraints must name a package and cannot specify extras or be editable.

Sources

Last reviewed: 19 October 2026.

Never miss an update

Weekly insights on software supply chain security, delivered to your inbox.

Self-healing security runs on Safeguard.

Your first fix PR is minutes away.

No sales call required, even your agent can complete the purchase over MCP.