How to Generate requirements.txt From What Your Code Actually Imports (pipreqs vs pip freeze)

2026年8月1日1 次浏览来源:Dev.to阅读原文

There's a file in most Python projects that everyone commits and nobody reads, and for two years ours was quietly lying to us.

If you've ever wondered how to generate a that reflects what your code actually needs - rather than every stray package that ever wandered into your virtualenv - this is the story of how I finally stopped trusting for that job and switched to .

Our file went from 214 packages to 23, and honestly the bigger relief was emotional: I could finally open it and believe what it told me.

Why this bugged me for years Every Python engineer knows the ritual.

Finish a feature, run , commit, move on.

It works.

Right up until it doesn't.

Ours had metastasized.

A new hire opened a PR and asked the most innocent question in code review: "Why does this API service depend on , , and ?" It didn't.

Those were tools somebody had -ed into the shared venv months earlier and never removed.

And does not care in the slightest what your code imports - it snapshots everything installed in the environment.

Our so-called source of truth was 90% noise, and I'd been squinting past it for so long I'd stopped seeing it.

That noise was not harmless, which is what finally pushed me to act.

Docker builds crawled, because all 214 packages got resolved and installed on every cold build.

Our vulnerability scanner shrieked about CVEs in libraries we never once imported.

And worst of all, nobody could tell which dependencies were real, so nobody dared delete any of them.

That last one is the quiet killer - a file so untrustworthy that fear freezes it in place. (I've watched the exact same fear freeze legacy test suites, so I recognized the smell immediately.) So I went looking for a better way to generate the thing, and the tool I'd criminally underused was , whose one-line pitch in its GitHub README is to "generate pip requirements.txt file based on imports of any project" - the exact opposite of what does.

In fairness to pip freeze I don't want to trash , because it isn't wrong - it's just answering a different question than I was asking.

The official pip docs are refreshingly blunt about this: it "reports what is installed; it does not compute a lockfile or a solver result." It answers "what is installed here," not "what does this code need." In a pristine, single-purpose virtualenv those two sets are identical.

In a real, long-lived dev environment they drift apart embarrassingly fast.

The canonical flow is exactly what you'd expect: If your venv is clean and dedicated to one project, that's genuinely the right tool - it captures exact versions of everything, which is precisely what you want for a fully reproducible environment.

Our problem was simply that our venv had become a junk drawer, and we'd been using a drawer-inventory tool to describe a shopping list.

The thing that finally clicked takes the opposite approach, and once I understood it I felt a little silly for not switching sooner.

It statically parses your files, finds the actual statements, maps them to PyPI packages, and writes only those.

Here's the whole sequence: The is just the current directory - walks it, reads the imports, and emits a containing only the libraries your code truly touches.

The README documents the flags worth knowing: to write elsewhere, to dump to stdout, and to compare an existing file against the project's real imports.

That's the entire change.

The generated file went from 214 lines to 23 - the same 23 packages the app had been importing all along, now finally the only 23 in the file.

The payoff rippled outward faster than I expected.

The final Docker image roughly halved, dropping from around 1.3 GB to a little over 600 MB.

A cold in CI went from nearly three minutes to under a minute.

Our scanner's findings on dependencies fell from thirty-one to six, and every one of those six was now a package we actually used, which meant we could actually triage them.

And for the first time, "can I delete this dependency?" became a question with an answer inst

分享
Baike.dev

baike.dev helps you discover great languages, frameworks, databases, DevOps and cloud-native tools.

Quick links

About

Contribute

Found a great developer tool? Share it with the community.

Submit a tool
© 2026 baike.dev Developer EncyclopediaUpdated daily · Discover great developer tools