Skip to content

pip-tools: Python Dependency Pinning Tools

pip-tools is a set of command-line utilities for managing Python dependency pinning. It consists of two commands: pip-compile for resolving and locking dependencies, and pip-sync for synchronizing a virtual environment to match a lockfile.

Note

uv provides uv pip compile and uv pip sync as faster, drop-in replacements for pip-tools. For new projects, uv is the recommended approach. pip itself added an experimental pip lock command in 25.1 (April 2025) that writes PEP 751 pylock.toml files, but pip lock locks to the current Python version and platform only. pip-tools remains useful for cross-platform requirements.txt generation.

pip-compile

pip-compile reads a set of direct dependencies and resolves them into a fully pinned requirements.txt file, including all transitive dependencies. It accepts input from requirements.in, pyproject.toml, setup.cfg, or setup.py.

# From requirements.in
pip-compile requirements.in

# From pyproject.toml
pip-compile pyproject.toml

# Upgrade all packages
pip-compile --upgrade requirements.in

# Upgrade a specific package
pip-compile --upgrade-package requests requirements.in

# Generate hashes for verification
pip-compile --generate-hashes requirements.in

A typical requirements.in file lists direct dependencies with loose constraints:

flask>=2.0
requests

Running pip-compile requirements.in produces a requirements.txt with pinned versions:

# This file is autogenerated by pip-compile with Python 3.12
blinker==1.9.0
    # via flask
certifi==2024.8.30
    # via requests
charset-normalizer==3.4.0
    # via requests
click==8.1.7
    # via flask
flask==3.1.0
    # via -r requirements.in
idna==3.10
    # via requests
itsdangerous==2.2.0
    # via flask
jinja2==3.1.4
    # via flask
markupsafe==3.0.2
    # via jinja2
requests==2.32.3
    # via -r requirements.in
urllib3==2.2.3
    # via requests
werkzeug==3.1.3
    # via flask

Each entry shows the exact version and which package required it.

pip-sync

pip-sync installs, upgrades, and removes packages so that the active virtual environment matches the lockfile exactly. Unlike pip install -r, which only adds and upgrades packages, pip-sync also removes packages that are not listed.

# Sync environment to a single lockfile
pip-sync requirements.txt

# Sync multiple lockfiles (e.g., production and development)
pip-sync requirements.txt dev-requirements.txt

Typical Workflow

  1. Maintain a requirements.in file with direct dependencies.
  2. Run pip-compile requirements.in to resolve and pin all versions.
  3. Run pip-sync requirements.txt inside a virtual environment to install the exact dependency set.
  4. When adding or upgrading a dependency, edit requirements.in and re-run pip-compile.

For projects using pyproject.toml as the dependency source, replace requirements.in with pyproject.toml in the commands above.

Limitations

  • Lockfiles are platform-specific. A lockfile generated on macOS may not resolve correctly on Linux.
  • Resolution speed is slower than uv.
  • No virtual environment creation. A tool like venv or virtualenv is still needed.
  • No Python version management.

Learn More

Last updated on

Please submit corrections and feedback...