← All articles
PythonTools

A Complete Guide to Python Virtual Environments

Stop fighting dependency conflicts. Learn what virtual environments are, why they matter, and how to create, activate, and share them with venv, pip, and requirements.txt — step by step.

If you have written more than one Python project, you have probably felt this pain: one project needs an old version of a library, another needs the newest one, and installing the second quietly breaks the first. Or you share your code, a teammate runs it, and it fails with a ModuleNotFoundError even though it works perfectly on your machine.

Virtual environments are the standard fix for all of this. They are one of the first habits that separate someone who writes Python scripts from someone who ships Python projects. This guide explains what they are, why they matter, and exactly how to use them — no prior experience required.

The Problem: One Python for Everything

When you install Python and run pip install, packages go into a single, shared location for that Python installation. Every project on your machine draws from that same global set of packages.

That works right up until two projects disagree. Imagine you maintain two web apps:

  • Project A was built last year and depends on Django 4.2.
  • Project B is brand new and needs Django 3.2 because of a plugin that hasn’t been updated.

A package can only exist in one version at a time in a shared installation. Install 3.2 for Project B and you have just downgraded Project A without meaning to. Install 4.2 again and you break Project B. There is no version of the global environment that makes both projects happy at once.

A diagram with two halves. The top half, labeled 'Without a virtual environment', shows Project A needing Django 4.2 and Project B needing Django 3.2 both pointing into one shared System Python, with a note that only one version can win. The bottom half, labeled 'With virtual environments', shows Project A pointing into its own venv with Django 4.2 and Project B pointing into a separate venv with Django 3.2, isolated with no conflicts.
Without isolation, two projects fight over one shared set of packages. A virtual environment gives each project its own private Python and its own package versions.

This is exactly the conflict the bottom half of the diagram solves.

The Solution: A Private Environment Per Project

A virtual environment is a self-contained folder that holds its own copy of the Python interpreter (really a lightweight link to it) and its own private site-packages directory where libraries are installed. When a virtual environment is active, python and pip point inside that folder instead of at the global installation.

The effect is simple but powerful:

  • Each project gets its own isolated set of packages and versions.
  • Installing or upgrading a package in one project cannot affect any other.
  • You can delete the whole environment and rebuild it from scratch in seconds.
  • You can hand the project to anyone and they can recreate your exact setup.

Python ships with a built-in tool for this called venv. You do not need to install anything extra.

Creating a Virtual Environment

Open a terminal, move into your project folder, and run:

# Move into your project
cd my-project

# Create a virtual environment in a folder named ".venv"
python -m venv .venv

That is the whole creation step. A new .venv folder appears in your project. The name .venv is just a convention — you could call it anything — but .venv is widely used because the leading dot keeps it tidy and tools recognize it.

python or python3?

On macOS and Linux you may need to type python3 instead of python. Run python3 --version to check what you have. On Windows, python is usually correct. Use whichever one prints a Python 3.x version.

Activating It

Creating the environment is not enough — you have to activate it so your shell knows to use it. The command differs by operating system:

# macOS / Linux
source .venv/bin/activate
# Windows (PowerShell)
.venv\Scripts\Activate.ps1
:: Windows (Command Prompt)
.venv\Scripts\activate.bat

Once active, your prompt changes to show the environment name in parentheses:

(.venv) you@computer my-project %

That little (.venv) is your signal that you are now working inside the isolated environment. From here, python and pip refer to the project’s private copies. You can confirm it:

# Should point inside your project's .venv folder
which python      # macOS / Linux
where python      # Windows

When you are done, leave the environment with a single command:

deactivate

Installing Packages

With the environment active, install packages exactly as you normally would:

pip install requests pandas

These land in .venv/, not in your global Python. To see what is installed in the current environment:

pip list

Because the environment is isolated, this list starts almost empty and only contains what this project needs. That is a feature: it keeps each project’s dependencies explicit and small.

Sharing Your Environment with requirements.txt

You should never commit the .venv folder itself to version control — it is large, machine-specific, and easy to rebuild. Instead, you record the list of packages your project needs and let others recreate the environment from that list.

Freeze your current packages into a file:

pip freeze > requirements.txt

This writes every installed package and its exact version, for example:

pandas==2.2.2
requests==2.32.3

Now anyone — including future you on a new laptop — can recreate the same environment:

# 1. Create and activate a fresh environment
python -m venv .venv
source .venv/bin/activate        # or the Windows command above

# 2. Install the exact same packages
pip install -r requirements.txt

This is the heart of reproducible Python projects. The code and the requirements.txt together are enough to rebuild the project anywhere.

Add .venv to .gitignore

Create a file named .gitignore in your project and add a single line:

.venv/

This keeps the environment folder out of Git while your requirements.txt (which you do commit) carries everything needed to rebuild it.

A Realistic Workflow

Put together, the day-to-day pattern for any new project looks like this:

# Start a new project
mkdir weather-app && cd weather-app

# Create and activate an isolated environment
python -m venv .venv
source .venv/bin/activate

# Install what you need
pip install requests

# ... write and run your code ...
python app.py

# Record dependencies so others can reproduce them
pip freeze > requirements.txt

# When you switch tasks
deactivate

Do this once per project and the “works on my machine” problem largely disappears.

Common Questions

Do I create one environment for everything, or one per project? One per project. That is the entire point — isolation. Sharing a single environment across projects reintroduces the conflicts you are trying to avoid.

Where should the environment live? Inside the project folder (as .venv) is the most common and convenient choice, because it travels with the project and is easy to find.

What if activation is blocked on Windows PowerShell? PowerShell may refuse to run the activation script due to its execution policy. You can allow it for your user with Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser, then activate again.

I see ModuleNotFoundError even though I installed the package. Almost always, the environment is not active, or you installed the package in a different environment. Check that your prompt shows (.venv) and that which python (or where python) points inside your project.

Beyond venv

venv is built in, simple, and enough for the vast majority of projects, which is why this guide focuses on it. As you grow, you will hear about other tools that solve the same isolation problem with extra features:

  • virtualenv — an older, faster third-party tool that works on more Python versions; venv was based on it.
  • conda — popular in data science because it manages non-Python dependencies (like compiled libraries) too.
  • Poetry and uv — modern project managers that combine environments, dependency resolution, and packaging in one tool.

They are worth exploring later, but none of them change the core idea you just learned. Master venv first, and the rest will feel familiar.

Summary

  • A virtual environment gives each project its own isolated Python and packages, so projects can’t break each other.
  • Create one with python -m venv .venv, then activate it (source .venv/bin/activate on macOS/Linux, .venv\Scripts\Activate.ps1 on Windows).
  • Install packages normally with pip; they stay inside the environment.
  • Save your dependencies with pip freeze > requirements.txt and rebuild anywhere with pip install -r requirements.txt.
  • Never commit .venv/ — commit requirements.txt instead.

Make this the first step of every Python project you start. It takes ten seconds and saves you hours of confusing, hard-to-debug problems down the line.

Want to go deeper into Python itself? Our free Python for Data Analytics course builds these professional habits in from the very beginning.

More from the blog