Python Virtual Environments

In the last lesson you learned about Python Packages. You saw how to bring in code other people wrote. Now there is a real problem waiting the moment you start a second project. Two projects can need two different versions of the same package. They will fight over which one wins. A virtual environment is the clean way to give each project its own box of packages. That way they never clash.

🤔 Why You Need Virtual Environments

Here is the pain. When you install a package the normal way, it goes into one shared place on your computer. Every project on that machine sees the same shared packages. So far that sounds fine, right? It is fine, until you have a second project that wants something different.

Now picture this. Alex has two projects on the same laptop:

  • Project A is older. It needs Django version 3.
  • Project B is brand new. It needs Django version 5.

Both cannot sit in the same shared place at once. If Alex installs Django 5 for Project B, then Project A suddenly breaks. If Alex puts Django 3 back, then Project B breaks. They keep stepping on each other. And it is not just two projects. Every package you install globally piles into the same shared pile. So over time the clashes get worse, not better.

A virtual environment fixes this in one move. You give each project its own private folder of packages. So Project A keeps its Django 3. Project B keeps its Django 5. Neither one knows the other exists.

Think of it like a separate toolbox for each project. The plumber does not throw every tool from every job into one giant bag. Each job gets its own neat box. You open the box for the job you are on, and only those tools are there. That is exactly what a virtual environment does for your packages.

📦 What a Virtual Environment Actually Is

In plain words, a virtual environment is an isolated folder. “Isolated” just means separate, on its own, not shared with anything else. That folder holds:

  • Its own copy of Python.
  • Its own set of installed packages, separate from the system Python and from every other project.

When the environment is active, any package you install lands inside that folder and nowhere else. Turn it off, and your system goes right back to normal. So the box only matters while you have it open.

Tip

One virtual environment per project. That is the habit. A new project gets a new environment, every time.

🛠️ Creating a Virtual Environment

Python already ships with the tool to make one. It is a built-in module called venv. So there is nothing extra to install. It comes with Python itself.

First, open your terminal and go into your project folder. Then run this command to create the environment:

Terminal window
python -m venv venv

Let’s read that line piece by piece:

  • python -m venv tells Python to run its built-in venv module.
  • The last venv is the name of the folder it will create. You could call it anything. But venv is the name everyone recognizes. Some people prefer .venv with a dot, so the folder hides a little. Both are fine. Just pick one and stay with it.

After it finishes, you will see a new venv folder sitting inside your project. That folder is the private box. You do not edit anything inside it by hand. You just create it once. Then you switch it on when you work.

Note

On some systems the command is python3 instead of python. If python -m venv venv says command not found, try python3 -m venv venv.

▶️ Activating It

Creating the environment is not enough. You have to activate it. That means telling your terminal to use this project’s box from now on. This is the step where most beginners get stuck. The command is different on each system. So find your setup below and use that exact line.

If you are on Windows and using PowerShell, run this inside your project folder:

Terminal window
venv\Scripts\Activate.ps1

If you are on Windows but using the old Command Prompt (cmd), run this instead:

Terminal window
venv\Scripts\activate.bat

If you are on Mac or Linux, run this:

Terminal window
source venv/bin/activate

Once it works, your terminal prompt changes. The name of the environment shows up in front of the line, usually in brackets:

Output

(venv) C:\Users\Alex\my-project>

That little (venv) at the start is your sign that the environment is on. Now anything you install with pip goes into this project’s box and stays there.

Want proof the switch actually happened? Ask your terminal which Python it is using now. The command is where python on Windows and which python on Mac or Linux:

Terminal window
# Windows
where python
# Mac / Linux
which python

When the environment is active, the path it prints points inside your venv folder, not to the system Python. So you can always check this if you are not sure which Python is running.

Here is the full flow from start to working environment:

  1. Go into your project folder

    Open the terminal and move into the folder for the project you are working on.

    Terminal window
    cd my-project
  2. Create the environment

    Run the venv module once. This makes the venv folder.

    Terminal window
    python -m venv venv
  3. Activate it

    Turn it on with the command for your system. After this you will see (venv) in the prompt.

    Terminal window
    # Windows PowerShell
    venv\Scripts\Activate.ps1
    # Windows cmd
    venv\Scripts\activate.bat
    # Mac / Linux
    source venv/bin/activate

📥 Installing Packages Inside It

Now the good part. With the environment active, you install packages the same way as always, with pip. The difference is where they land. They go into this project’s box, not the shared system space.

Let’s say this project needs the requests package. With (venv) showing in your prompt, run:

Terminal window
pip install requests

That is it. The requests package is now sitting inside this project’s venv folder. Open a second project, activate its own environment, and that one will not have requests unless you install it there too. So each project carries only what it actually needs. Clean and separate, just like we wanted.

🧾 Saving and Recreating the Environment

Here is a question that comes up fast. Your teammate clones the project, or you move to a new laptop. How do they get the exact same packages you have? You do not send them the venv folder. Instead you save a simple list of what is inside it.

Run this with the environment active:

Terminal window
pip freeze > requirements.txt

Let’s read that line:

  • pip freeze prints every package in the current environment, with its exact version number.
  • > requirements.txt saves that list into a file called requirements.txt.

Open the file and you will see something plain like this:

Output

requests==2.31.0
urllib3==2.0.7
certifi==2023.7.22

Each line is a package name and the exact version, locked down. Now anyone with this file can rebuild the same environment. They create their own fresh venv, activate it, and run:

Terminal window
pip install -r requirements.txt

The -r flag means “read the list from this file.” Pip goes down the list and installs every package at the version written there. So they end up with the same setup you have, package for package.

This is what people mean by a reproducible project. “Reproducible” means anyone can rebuild it and get the same result. The pinned versions are the key part. Without them, one person might get requests version 2.31 and another gets 2.40, and now the project behaves differently on two machines. With requirements.txt, everyone is on the same versions. So bugs are easier to track down and “works on my machine” stops being a problem.

🙈 Keep the venv Out of Git

One short but important rule. You commit requirements.txt to Git. You do not commit the venv folder. The folder is large and it is tied to one machine, so it is useless to anyone else. The requirements.txt file is tiny and rebuilds the whole thing.

So add one line to your .gitignore file:

venv/

That tells Git to skip the folder. Your teammates pull the repo, see requirements.txt, build their own venv, and they are ready. They never need your copy of the folder.

🧰 Other Tools You Might Hear About

As you read around, you will see other names come up: virtualenv, conda, poetry, and uv. They all deal with the same idea of isolated environments and managing packages, just with extra features layered on top. Some are faster, some bundle in more project management, some are popular in data science. They are worth knowing about later. But you do not need any of them to start. The built-in venv ships with Python and does everything covered here. So learn venv first, get comfortable, and reach for the others only when a project actually asks for them.

⏹️ Deactivating It

When you are done working on the project, you switch the environment off. This one command is the same on every system:

Terminal window
deactivate

The (venv) disappears from your prompt. Your terminal goes back to using the system Python. You do not delete the folder. You just turn it off. The folder stays exactly where it is. Next time you come back to the project, you activate it again and everything is right where you left it.

Here is a quick map of the commands so you can see them side by side:

What you want Command
Create the environment python -m venv venv
Activate on Windows (PowerShell) venv\Scripts\Activate.ps1
Activate on Windows (cmd) venv\Scripts\activate.bat
Activate on Mac / Linux source venv/bin/activate
Save the package list pip freeze > requirements.txt
Rebuild from the list pip install -r requirements.txt
Turn it off (any system) deactivate

⚠️ Common Mistakes

A few things trip people up early. Watch for these.

  • Forgetting to activate before installing. If you run pip without seeing (venv) in your prompt, the package goes into the shared system space, not your project. Always check for (venv) first.

  • Installing globally by mistake. This is the same slip from the other side. No (venv), no isolation. The package spreads to every project and the version clashes come right back. Glance at your prompt before every pip install.

  • Using the wrong activate command for your system. Windows PowerShell uses venv\Scripts\Activate.ps1. Mac and Linux use source venv/bin/activate. They are not interchangeable.

Terminal window
# ❌ Avoid: running the Mac command on Windows
source venv/bin/activate
# ✅ Good: on Windows PowerShell use this
venv\Scripts\Activate.ps1
  • Committing the venv folder to Git. The folder is tied to one machine and it is large. You never copy it into a teammate’s machine and you never commit it. Commit requirements.txt instead, and add venv/ to .gitignore.

  • Reusing one environment for every project. That defeats the whole point. The version clashes come right back. One project, one environment.

✅ Best Practices

Small habits that keep your projects clean.

  • Make the environment the first thing you do when starting a new project, before you install anything.
  • Name the folder venv (or .venv) so every project looks the same and your tools recognize it.
  • Add venv/ to your .gitignore file early so the folder never gets committed by accident.
  • Run pip freeze > requirements.txt whenever you add a package, so the list always matches what you have.
  • Activate the environment every time you sit down to work. Deactivate when you switch to a different project.

Caution

The venv folder can be large and is specific to your machine. Committing it to Git is a common slip. Add venv/ to .gitignore early, and commit requirements.txt instead.

🧩 What You’ve Learned

A quick recap before you move on.

  • ✅ Why projects clash: installed packages go into one shared place, so two projects needing different versions fight over it.
  • ✅ A virtual environment is an isolated folder with its own Python and its own packages, separate from everything else.
  • ✅ You create one with python -m venv venv, which makes a venv folder in your project.
  • ✅ You activate it with venv\Scripts\Activate.ps1 on Windows PowerShell, venv\Scripts\activate.bat on cmd, and source venv/bin/activate on Mac or Linux.
  • ✅ With it active, pip install puts packages into this project’s box, and where python / which python confirms which Python is running.
  • pip freeze > requirements.txt saves the exact versions, and pip install -r requirements.txt rebuilds the same setup anywhere.
  • ✅ You turn it off with deactivate, and you commit requirements.txt but keep the venv folder out of Git.

Check Your Knowledge

Test what you learned. Pick an answer for each question, then click Check.

  1. 1

    What problem does a virtual environment solve?

    Why: A virtual environment gives each project its own isolated set of packages, so two projects needing different versions never fight.

  2. 2

    Which command creates a virtual environment in the current folder?

    Why: `python -m venv venv` runs Python's built-in venv module and makes a folder named venv.

  3. 3

    How do you save the exact package versions so the project can be rebuilt elsewhere?

    Why: pip freeze writes the pinned versions to requirements.txt; pip install -r requirements.txt rebuilds the same setup. You commit the file, not the venv folder.

  4. 4

    What command turns the environment off?

    Why: `deactivate` switches the environment off and is the same on Windows, Mac, and Linux.

🚀 What’s Next?

You can isolate a project now. So the next step is the tool that actually installs packages into that isolated box.

pip Package Manager

Share & Connect