sethserver.com Subscribe
Python Virtual Environments and Dependency Management: A Practical Guide for Developers

Python Virtual Environments and Dependency Management: A Practical Guide for Developers

By Seth Black • Updated: March 18, 2026

Python · 3 min read

Like this kind of writing? Get one email a week with notes on startups, AI, and the occasional strong opinion about Python: subscribe to the newsletter.

Programmers love to argue about "best practices" like movie nerds argue about director's cuts. Everyone's convinced their version is the only sane one. Mine isn't the best. It just keeps me from throwing my laptop out a window at 2am when pip decides to install the wrong version of everything.

This is my opinionated, practical guide for Python environments and dependencies. Works for new projects. Works for jumping into someone else's repo. Keeps you from breaking your global Python install and questioning your life choices.

Step 0: Read the docs (yes, really)

I still waste hours before realizing the answer was in the README the whole time. You skim, you assume, you waste an hour debugging. Then you read the README: "Use Python 3.10." Oh. Right.

If you're joining a project? Check these first:

Step 1: Pick the right Python version

Here's what I do:

You can have multiple Python versions on one machine. That's how it's supposed to work.

Windows: use the Python Launcher (py).
Mac/Linux: I use pyenv.

I'm using Python 3.12.1 for these examples.

Check what you've got:

py -0p
py -3.12 --version

Step 2: Keep your projects in one place

I'm boring about this, but it matters. Everything goes under one directory. Mine is:

Inside that, I name folders by repo or domain. Consistency beats cleverness.

Example:

C:\Users\seth\Programming
├── findmenoms.com
├── fiscus.io
├── gift-exchange-2023
├── kdramabookclub.com
├── llama
├── mindyourink
├── quimbyapp.com
└── sethserver.com

This matters more than it should. Half the time someone says "my Python is broken," they're just in the wrong directory with three different venvs activated somehow.

Step 3: Make a virtual environment (every time)

I'm strict about this.

Never install project packages into your root Python.
Every project gets its own venv. No exceptions.

Break this rule once and you'll spend three hours figuring out why requests is version 2.18 and you have no idea when you installed it.

Create the project and venv:

mkdir venvexample
cd venvexample
py -m venv env

Activate it:

.\env\Scripts\activate

Your prompt should change:

(env) PS C:\Users\seth\Programming\venvexample>

No (env) in your prompt? Stop. Don't keep going.

Otherwise you're installing into global Python and tomorrow you'll be confused why Flask works in one project but not another.

Step 4: Install dependencies with pip

There are other tools. Poetry, pipenv, whatever. I keep using pip because it's simple and it works.

Let's install Flask:

pip install flask

You'll see something like this:

Collecting flask
  Downloading flask-3.0.0-py3-none-any.whl
Collecting Werkzeug>=3.0.0
Collecting Jinja2>=3.1.2
Collecting click>=8.1.3
Collecting itsdangerous>=2.1.2
Collecting blinker>=1.6.2
Collecting colorama
Collecting MarkupSafe>=2.0
Installing collected packages: MarkupSafe, colorama, itsdangerous, click, blinker, Werkzeug, Jinja2, flask
Successfully installed Jinja2-3.1.2 MarkupSafe-2.1.3 Werkzeug-3.0.1 blinker-1.7.0 click-8.1.7 colorama-0.4.6 flask-3.0.0 itsdangerous-2.1.2

That dependency list is why you need venvs. Your app is never "just Flask." It's Flask plus eight other libraries. Keep that mess inside the project.

Step 5: Freeze dependencies to requirements.txt

This is how you save your setup.

pip freeze > requirements.txt

Now someone else (or you in three months when you forgot everything) can run:

pip install -r requirements.txt

...and get the exact same setup.

Step 6: When your venv breaks, just delete it

Venv acting weird? Delete it and make a new one. Seriously.

Virtual environments are meant to be disposable. That's the whole point.

If your whole Python install is cursed, I wrote about that too: Fixing a Broken Python Environment (P.S. yes, the URL is real, and yes, I've had to fix broken Python installs more times than I want to admit).

-Sethers

Share this post
Newsletter

One email, once a week.

Notes on databases, systems, and the occasional strong opinion about Python. No spam, unsubscribe anytime.

Seth Black
Written by

Seth Black

Engineer and founder based in Texas. Writes about databases, AI, and running things in production. Embeds in small teams as lead engineer.

More from Python

View all →
Python

OpenAI Bought Astral - and my fav tool uv

Mar 23, 2026
Python

Python Pydantic Validation: Stop Writing Manual Checks

Mar 04, 2026
Python

Python asyncio Recipes

Mar 04, 2026