HackerReposA FIELD GUIDE TO OPEN SOURCE
ProSponsor the shelf♧ 0
← Back to top all-time
pypa
pip-tools
Python2013–2026
pypa / pip-tools

pip-tools

A set of tools to keep your pinned Python dependencies fresh.

59Distinct people
64Mentions
1Explicit recommenders
8KGitHub stars
REPOSITORY AT A GLANCE

What to know before exploring

What it is

A set of tools to keep your pinned Python dependencies fresh.

GitHub

Where it is used

No documented product use was verified in the last source check.

What people are saying

I personally still find Poetry and Pipenv to be a little heavy-handed for my preferred workflows. To that end, pip-tools [1] is what I recommend to those who feel similarly. It…

arusahni used a recommendation phrase. One indexed comment matches. This is a phrase match, not a verdict.

No classified warning is attached to this page. Read the discussions before treating silence as approval.

Also in these discussions

Mentioned in the same Hacker News threads. That is not proof they are substitutes.

This week on Hacker News

Nov 8–Nov 15 UTC · Direct repository links and separately labeled related project stories. Indexed through 11/15/2026, 2:04:58 PM UTC.

No direct repository links were found in the indexed HN discussions over the past seven days. Older discussions are available below.

Mentions over time

HN mentions by year64 dated mentions

Observed mentions: 2013-01-28 21:40:52 UTC to 2026-03-19 16:14:21 UTC.

0510152013-01-01 00:00:00 UTC to 2014-01-01 00:00:00 UTC (exclusive): 4 mentions; 1 submissions, 3 comments20132014-01-01 00:00:00 UTC to 2015-01-01 00:00:00 UTC (exclusive): 0 mentions; 0 submissions, 0 comments2015-01-01 00:00:00 UTC to 2016-01-01 00:00:00 UTC (exclusive): 0 mentions; 0 submissions, 0 comments2016-01-01 00:00:00 UTC to 2017-01-01 00:00:00 UTC (exclusive): 14 mentions; 1 submissions, 13 comments2017-01-01 00:00:00 UTC to 2018-01-01 00:00:00 UTC (exclusive): 4 mentions; 1 submissions, 3 comments2018-01-01 00:00:00 UTC to 2019-01-01 00:00:00 UTC (exclusive): 7 mentions; 0 submissions, 7 comments2019-01-01 00:00:00 UTC to 2020-01-01 00:00:00 UTC (exclusive): 6 mentions; 0 submissions, 6 comments20192020-01-01 00:00:00 UTC to 2021-01-01 00:00:00 UTC (exclusive): 6 mentions; 0 submissions, 6 comments2021-01-01 00:00:00 UTC to 2022-01-01 00:00:00 UTC (exclusive): 6 mentions; 0 submissions, 6 comments2022-01-01 00:00:00 UTC to 2023-01-01 00:00:00 UTC (exclusive): 11 mentions; 0 submissions, 11 comments2023-01-01 00:00:00 UTC to 2024-01-01 00:00:00 UTC (exclusive): 1 mentions; 0 submissions, 1 comments2024-01-01 00:00:00 UTC to 2025-01-01 00:00:00 UTC (exclusive): 2 mentions; 0 submissions, 2 comments2025-01-01 00:00:00 UTC to 2026-01-01 00:00:00 UTC (exclusive): 1 mentions; 0 submissions, 1 comments2026-01-01 00:00:00 UTC to 2027-01-01 00:00:00 UTC (exclusive): 2 mentions; 0 submissions, 2 comments. Incomplete calendar period.2026*

* An incomplete calendar period is marked with an outlined bar. Its count is not directly comparable with a full period.

Counts come from the repository’s dated source evidence. Index cutoff: 2026-11-02 08:16:59 UTC.

View mention counts and date ranges
UTC ranges include their start and exclude their end. Select a period to filter the source evidence.
PeriodStart (UTC)End (exclusive, UTC)MentionsSubmissionsComments
20132013-01-01 00:00:00 UTC2014-01-01 00:00:00 UTC413
20142014-01-01 00:00:00 UTC2015-01-01 00:00:00 UTC000
20152015-01-01 00:00:00 UTC2016-01-01 00:00:00 UTC000
20162016-01-01 00:00:00 UTC2017-01-01 00:00:00 UTC14113
20172017-01-01 00:00:00 UTC2018-01-01 00:00:00 UTC413
20182018-01-01 00:00:00 UTC2019-01-01 00:00:00 UTC707
20192019-01-01 00:00:00 UTC2020-01-01 00:00:00 UTC606
20202020-01-01 00:00:00 UTC2021-01-01 00:00:00 UTC606
20212021-01-01 00:00:00 UTC2022-01-01 00:00:00 UTC606
20222022-01-01 00:00:00 UTC2023-01-01 00:00:00 UTC11011
20232023-01-01 00:00:00 UTC2024-01-01 00:00:00 UTC101
20242024-01-01 00:00:00 UTC2025-01-01 00:00:00 UTC202
20252025-01-01 00:00:00 UTC2026-01-01 00:00:00 UTC101
2026 (partial)2026-01-01 00:00:00 UTC2027-01-01 00:00:00 UTC202

From the project README

An excerpt from the repository, fetched Nov 13, 2026.

Read the project’s introduction
pip-tools = pip-compile + pip-sync A set of command line tools to help you keep your pip-based packages fresh, even when you've pinned them. You do pin them, right? (In building your Python application and its dependencies for production, you want to make sure that your builds are predictable and deterministic.) Installation Similar to pip, pip-tools must be installed in each of your project's virtual environments: $ source /path/to/venv/bin/activate (venv) $ python -m pip install pip-tools Note: all of the remaining example commands assume you've activated your project's virtual environment. Example usage for pip-compile The pip-compile command lets you compile a requirements.txt file from your dependencies, specified in either pyproject.toml, setup.cfg, setup.py, or requirements.in. Run it with pip-compile or python -m piptools compile (or pipx run --spec pip-tools pip-compile if pipx was installed with the appropriate Python version). If you use multiple Python versions, you can also run py -X.Y -m piptools compile on Windows and pythonX.Y -m piptools compile on other systems. pip-compile should be run from the same virtual environment as your project so conditional dependencies that require a specific Python version, or other environment markers, resolve relative to your project's environment. Note: If pip-compile finds an existing requirements.txt file that fulfils the dependencies then no changes will be made, even if updates are available. To compile from scratch, first delete the existing requirements.txt file, or see Updating requirements for alternative approaches. Requirements from pyproject.toml The pyproject.toml file is the latest standard for configuring packages and applications, and is recommended for new projects. pip-compile supports both installing your project.dependencies as well as your project.optional-dependencies. Thanks to the fact that this is an official standard, you can use pip-compile to pin the dependencies in projects that use modern standards-adhering packaging tools like Setuptools, Hatch or flit. Suppose you have a 'foobar' Python application that is packaged using Setuptools, and you want to pin it for production. You can declare the project metadata as: [build-system] requires = ["setuptools", "setuptools-scm"] build-backend = "setuptools.build_meta" [project] requires-python = ">=3.9" name = "foobar" dynamic = ["dependencies", "optional-dependencies"] [tool.setuptools.dynamic] dependencies = { file = ["requirements.in"] } optional-dependencies.test = { file = ["requirements-test.txt"] } If you have a Django application that is packaged using Hatch, and you want to pin it for production. You also want to pin your development tools in a separate pin file. You declare django as a dependency and create an optional dependency dev that includes pytest: [build-system] requires = ["hatchling"] build-backend = "hatchling.build" [project] name = "my-cool-django-app" version = "42" dependencies = ["django"] [project.optional-dependencies] dev = ["pytest"] You can produce your pin files as easily as: $ pip-compile -o requirements.txt pyproject.toml # # This file is autogenerated by pip-compile with Python 3.10 # by the following command: # # pip-compile --output-file=requirements.txt pyproject.toml # asgiref==3.6.0 # via django django==4.1.7 # via my-cool-django-app (pyproject.toml) sqlparse==0.4.3 # via django $ pip-compile --extra dev -o dev-requirements.txt pyproject.toml # # This file is autogenerated by pip-compile with Python 3.10 # by the following command: # # pip-compile --extra=dev --output-file=dev-requirements.txt pyproject.toml # asgiref==3.6.0 # via django attrs==22.2.0 # via pytest django==4.1.7 # via my-cool-django-app (pyproject.toml) exceptiongroup==1.1.1 # via pytest iniconfig==2.0.0 # via pytest packaging==23.0 # via pytest pluggy==1.0.0 # via pytest pytest==7.2.2 # via my-cool-django-app (pyproject.toml) sqlparse==0.4.3 # via django tomli==2.0.1 # via pytest This is great for both pinning your applications, but also to keep the CI of your open-source Python package stable. Requirements from setup.py and setup.cfg pip-compile has also full support for setup.py- and setup.cfg-based projects that use setuptools. Just define your dependencies and extras as usual and run pip-compile as above. Requirements from requirements.in You can also use plain text files for your requirements (e.g. if you don't want your application to be a package). To use a requirements.in file to declare the Django dependency: # requirements.in django Now, run pip-compile requirements.in: $ pip-compile requirements.in # # This file is autogenerated by pip-compile with Python 3.10 # by the following command: # # pip-compile requirements.in # asgiref==3.6.0 # via django django==4.1.7 # via -r requirements.in sqlparse==0.4.3 # via django And it will produce your requirements.txt, with all the Django dependencies (and all underlying dependencies) pinned. (updating-requirements)= Updating requirements pip-compile generates a requirements.txt file using the latest versions that fulfil the dependencies you specify in the supported files. If pip-compile finds an existing requirements.txt file that fulfils the dependencies then no changes will be made, even if updates are available. To force pip-compile to update all packages in an existing requirements.txt, run pip-compile --upgrade. To update a specific package to the latest or a specific version use the --upgrade-package or -P flag: # only update the django package $ pip-compile --upgrade-package django # update both the django and requests packages $ pip-compile --upgrade-package django --upgrade-package requests # update the django package to the latest, and requests to v2.0.0 $ pip-compile --upgrade-package django --upgrade-package requests==2.0.0 You can combine --upgrade and --upgrade-package in one command, to provide constraints on the a
Read the full README on GitHub

What Hacker News says

6 sources
FWIW I had a lot of success using https://github.com/jazzband/pip-tools to have dependencies automatically managed in a virtualenv. * Basically I would have a single bash script that every `.py` entrypoint links to. * Beside that symlink is a `requirements.in` file that just lists the top-level dependencies I know about. * There's a `requirements.txt` file generated via pip-tools that lists all the dependencies with explicit version numbers. * The bash script then makes sure there's a virtual environment in that folder & the installed package list matches exactly the `requirements.txt` file (i.e. any extra packages are uninstalled, any missing/mismatched version packages are installed correctly). This was great because during development if you want to add a new dependency or change the installed version (i.e. pip-compile -U to update the
Read the rest
dependency set), it didn't matter what the build server had & could test any diff independently & inexpensively. When developers pulled a new revision, they didn't have to muck about with the virtualenv - they could just launch the script without thinking about python dependencies. Finally, unrelated pieces of code would have their own dependency chains so there wasn't even a global project-wide set of dependencies (e.g. if 1 tool depends on component A, the other tools don't need to). I viewed the lack of `setup.py` as a good thing - deploying new versions of tools was a git push away rather than relying on chef or having users install new versions manually. This was the smoothest setup I've ever used for running python from source without adopting something like Bazel/BUCK (which add a lot of complexity for ingesting new dependencies as you can't leverage pip & they don't support running the python scripts in-place).
In Guido van Rossum joins Microsoft
I strongly recommend https://github.com/jazzband/pip-tools to solve this. It provides a simple script to take a requirements file and "compile" a full specification of all transitive dependencies. You check both files into the repo, point pip at the generated file, and manually modify the other one. It means you often don't need to pin requirements manually at all, and the versions will be explicitly updated whenever you choose to recompile your requirements.
In The creeping scourge of tooling config files in project root directories
How does this solve the problem? As I can tell it replaces a centralized dependencies (requirements.txt) containing references to a known and trusted registry (pypi.org) with url's in all files across your project (and 3rd party library's files). Making maitenance only harder and security updates even more so. And making it harder to debug things as you now keep in mind that multiple versions of the same packages can be used in your source. Also, requirements.txt already support's urls if you want your sources from other places. For me, most of the pain with the Python packaging went away after I started using Pip-tools[0]. It's just a simple utility to add lockfile capabilities to Pip. Nothing new to learn, no new filosophies or paradigm's. No PEP waiting to be adopted by everyone. Just good old requirements.txt + Pip. [0] https://github
Read the rest
In Python Wheels Crosses 90%
When I was at Google I had a similar problem (team wasn't using Blaze). So what I did was to have a wrapper entrypoint around every python entrypoint that would just run that python entrypoint (e.g. foo would execute foo.py). The advantage was that the shell script would first set up a virtual environment for every entrypoint and install all the packages in the requirements.txt that was beside the entrypoint (removing any new ones). Each requirements.txt was compiled from a requirements.in file via pip-sync [1] which meant that devs only had to worry about declaring just the packages they actually directly depended on. Any change to requirements.in would require you to have run pip-sync which wouldn't (by default) upgrade any packages & only lock whatever the current version is (automation unit tests would validate that every requirements
Read the rest
.txt matched the requirements.in file). This didn't solve the multiple versions of python on the host. That was managed by having a bootstrap script written in python2 that would set up the development environment to a consistent state (i.e. install homebrew, install required packages) that anyone wanting to run the tools would run (no "getting started guides") which also versioned itself & was idempotent (generally robust against running multiple times). We also shipped this to our external partners in the factory. Generally worked well as once you ran the necessary scripts once no further internet access was required. It wasn't easy but eventually it worked super reliably. [1] https://github.com/jazzband/pip-tools
In Hypermodern Python

MAKE YOURSELF AT HOME

A few shortcuts

/
Search the collection
?
Open this guide
Esc
Close dialogs and navigation

Your saved repositories and interests stay in this browser.