Pinning Python Dependencies With requirements.txt
How to record the exact package versions a project needs and rebuild the same environment on another machine. After this, "it works on my computer" stops being the answer.
Course content
Sign in to save your progress.
-
Set Up Projects That Don't Break Each Other
-
Python Virtual Environments and pip: One Project, One Environment
-
Pinning Python Dependencies With requirements.txt
-
-
-
Organize Code Other People Can Read
-
Python Modules and Packages: Splitting One Big File
-
Python Imports: Why ModuleNotFoundError Keeps Happening
-
Python Classes: When a Dictionary Is No Longer Enough
-
-
-
Work With Real Files
-
Python File Handling: Open, Read, Write, and Always Use with
-
Python pathlib: Stop Building File Paths by Hand
-
Reading, Cleaning and Writing CSV Data in Python
-
-
-
Shorter Code That Still Says What It Does
-
Python Comprehensions: Lists, Sets and Dictionaries
-
When a Comprehension Should Be a Plain Loop
-
-
-
Prove It Works Before Someone Else Finds Out
-
Python Testing Basics With pytest
-
Debugging Python With print, logging and pdb
-
-
- Final Check: Python Intermediate
A virtual environment is disposable. The list of what goes into it is not. requirements.txt is that list: a plain text file with the packages, and ideally the exact versions, your project needs. With it, anyone can rebuild your environment with one command.
Skip ahead: If you already pin versions, rebuild environments from requirements.txt, and know the difference between pinning an app and a library, take the section quiz.
Why this matters
"It works on my computer" usually means "my computer has different package versions than yours". You installed a library eight months ago. Your coworker installs it today and gets a newer version that changed a function. Same code, different result. Nobody did anything wrong. The project just never wrote down what it depends on.
Create the file with pip freeze
Inside an activated environment, pip freeze prints every installed package with its exact version:
python3 -m venv .venv
source .venv/bin/activate
python -m pip install --quiet requests
python -m pip freeze > requirements.txt
cat requirements.txt
certifi==...
charset-normalizer==...
idna==...
requests==2...
urllib3==...
You installed one package and got five lines. The other four are dependencies of requests. That is normal. Freezing them too means the whole set is reproducible, not just the part you remember installing.
⚠ Warning: Only run pip freeze inside the project's activated environment. Run it against your global Python and you get every package you ever installed for every project, and the file becomes useless.
Rebuild the environment from the file
On a new computer, or after deleting a broken .venv:
python3 -m venv .venv
source .venv/bin/activate # Windows: .venv\Scripts\activate
python -m pip install -r requirements.txt
To prove it gives the same result, build a second environment from the same file and compare it with the original list:
python3 -m venv new-env
new-env/bin/python -m pip install --quiet -r requirements.txt
new-env/bin/python -m pip freeze | diff - requirements.txt && echo "Same versions"
Same versions
Two environments, built at different times, with identical versions. That is what you want for anything that has to behave the same everywhere.
Pinned or loose versions?
There are three common ways to write a line, and they are not equally safe.
requests==2.32.3(pinned). Exactly this version. Best for applications and scripts you deploy: the same code gets the same packages every time. The downside is that you don't get bug fixes until you update the pin yourself.requests>=2.31,<3(a range). Any version in that range. Better for libraries that other projects install, because strict pins in a library cause conflicts with the projects using it.requests(nothing). Whatever is newest on the day someone installs. Fine for a quick experiment. For anything else, you are betting that no future release changes anything you use.
For most people taking this course, the answer is simple: you are writing applications and scripts, so pin. The range style matters later, when you publish a package, which is covered in the Python Advanced course.
Updating on purpose
Pinning doesn't mean never updating. It means updating when you decide to, not when a release happens to come out. A safe routine:
- Check what is outdated with
python -m pip list --outdated. - Upgrade one package, for example
python -m pip install --upgrade requests. - Run your tests or at least run the script.
- If it works, freeze again and commit the new
requirements.txt. If it doesn't, you know exactly which upgrade broke it.
A real-world example
A small team has a script that pulls orders from an API every morning. A new hire sets it up on a fresh laptop. Without a requirements file, they install whatever is newest, and one of the libraries changed how it handles dates. The script runs without errors and quietly writes the wrong dates. With a pinned requirements.txt in the repository, the new laptop gets the same versions as the server, and the problem never happens.
Common mistakes
- Freezing the global Python. Covered above. Check that the environment is active first.
- Editing requirements.txt by hand and forgetting dependencies. If you add a line by hand, install from the file and freeze again so the dependencies get pinned too.
- Not committing it. The file is useless if it only lives on your computer. It belongs in Git, next to your code.
.venvdoesn't. - Installing extra tools into the project environment. Things you use only for yourself, like a different code formatter, end up in the freeze. Some projects keep them in a separate
requirements-dev.txt.
💡 Tip: Test your file the honest way once in a while: delete .venv, create a new one, install from requirements.txt, and run the project. If it fails, the file is incomplete, and it is better you find out than the next person.
What happens if you skip this step
The project works for as long as it lives on one computer with one environment. The day it has to run anywhere else, a server, a coworker's laptop, your own new laptop, someone has to guess the versions. Guessing usually works. When it doesn't, the bug looks like a bug in your code, and you spend hours in the wrong place.
If your laptop died today, would your project still run on the next one exactly the same way?
About
How to record the exact package versions a project needs and rebuild the same environment on another machine. After this, "it works on my computer" stops being the answer.
- Duration
- 5 min
- Last update
- 09/19/2026
Comments (0)
Sign in to commentNo comments yet.