Python Virtual Environments (venv)
Learn how to create, activate, and manage Python virtual environments with venv. Covers pip integration, requirements files, and common workflows.
A virtual environment is a self-contained directory that holds a private copy of a Python interpreter and its own site-packages folder. Packages you install inside a virtual environment are completely isolated from your system Python and from every other environment on your machine — so two projects can depend on different versions of the same library without ever conflicting.
This chapter covers why virtual environments matter, how to create and activate them with the built-in venv module, how to manage dependencies with pip, and the everyday workflow most Python projects follow.
Why virtual environments matter
Imagine you have two projects on the same machine:
- Project A requires
requests==2.28.0 - Project B requires
requests==2.31.0
If you install both versions into the global Python environment, pip simply overwrites whichever version it installed first. One project will break. Virtual environments solve this by giving each project its own isolated site-packages directory, so both versions coexist without touching each other.
Other practical benefits:
| Benefit | Explanation |
|---|---|
| Reproducibility | Freeze an exact dependency list and share it — teammates get the identical setup |
| Clean uninstall | Delete the environment folder and the project's packages are completely gone |
No sudo required | Packages install into your home directory, not system paths |
| Multiple Python versions | Point different environments at different Python interpreters |
Creating a virtual environment
Python 3.3 and later include venv in the standard library — no installation needed.
python -m venv .venvThis creates a .venv directory in your current folder. The name .venv is a common convention (the leading dot hides it on Unix-like systems), but you can use any name you like — env, venv, or even a project-specific name.
What venv creates inside .venv:
.venv/
├── bin/ # Python interpreter + activation scripts (Linux/macOS)
│ ├── activate
│ ├── python -> python3
│ └── pip
├── include/
├── lib/
│ └── python3.x/
│ └── site-packages/ # Installed packages go here
└── pyvenv.cfg # Records the Python version and base prefixOn Windows the layout differs slightly — bin/ is Scripts/ and path separators are backslashes.
Choosing a specific Python version
If you have multiple Python versions installed, pass the interpreter explicitly:
python3.11 -m venv .venvOr on Windows:
py -3.11 -m venv .venvThe pyvenv.cfg file inside the environment records which interpreter was used, so the environment always runs with that version.
Activating the environment
Creating the environment does not automatically use it. You must activate it, which prepends the environment's bin/ directory to your PATH so that python and pip resolve to the environment's copies.
macOS and Linux:
source .venv/bin/activateWindows (Command Prompt):
.venv\Scripts\activate.batWindows (PowerShell):
.venv\Scripts\Activate.ps1After activation, your shell prompt usually shows the environment name in parentheses:
(.venv) $ python --version
Python 3.12.3
(.venv) $ which python
/your/project/.venv/bin/pythonEvery pip install command you run while the environment is active installs into .venv/lib/.../site-packages/, never into the system Python.
Deactivating
When you are done working on the project, or want to switch to a different environment:
deactivateYour shell prompt returns to normal and python resolves to the system interpreter again.
Installing packages inside a virtual environment
With the environment active, use pip normally:
pip install requests flaskConfirm the packages landed in the right place:
pip show requestsThe Location: line in the output should point into your .venv directory.
Checking what is installed
pip listA freshly created environment typically contains only pip and setuptools. Everything else you see is something you (or a requirements file) installed explicitly.
Saving and restoring dependencies
Exporting a requirements file
Once your environment is set up, freeze the exact package versions so anyone can reproduce it:
pip freeze > requirements.txtA typical requirements.txt looks like:
certifi==2024.2.2
charset-normalizer==3.3.2
flask==3.0.3
idna==3.6
requests==2.31.0
urllib3==2.2.1Commit requirements.txt to version control. Do not commit the .venv directory itself — add it to .gitignore.
Restoring from a requirements file
On a new machine or in a fresh clone:
python -m venv .venv
source .venv/bin/activate # or the Windows equivalent
pip install -r requirements.txtThis recreates an environment identical to the one you froze.
Standard project workflow
Most Python projects follow this sequence:
# 1. Clone the repository
git clone https://github.com/example/myproject.git
cd myproject
# 2. Create a virtual environment
python -m venv .venv
# 3. Activate it
source .venv/bin/activate
# 4. Install dependencies
pip install -r requirements.txt
# 5. Work on the project ...
# 6. When you add a new package, update the requirements file
pip install newpackage
pip freeze > requirements.txtWhat to add to .gitignore
Never commit the environment directory to version control — it contains compiled binaries, is platform-specific, and can be tens of megabytes. Add one of these patterns to your .gitignore:
# Virtual environment
.venv/
venv/
env/Commit only requirements.txt (or pyproject.toml + requirements.txt). That is all anyone needs to rebuild the environment from scratch.
venv versus other tools
venv is the built-in solution and sufficient for most use cases. You may also encounter these alternatives:
| Tool | What it adds over venv |
|---|---|
virtualenv | Faster creation, works with Python 2, more options |
pipenv | Combines venv + pip into a single tool with Pipfile |
poetry | Full dependency resolver, build system, and publishing tool |
conda | Manages non-Python dependencies (C libraries, R packages, etc.) — popular in data science |
uv | Extremely fast Rust-based replacement for pip + venv |
For most beginners and straightforward projects, python -m venv is the right choice — it ships with Python and requires no extra installation.
Common errors and fixes
"python: command not found" when creating the environment
On some Linux distributions Python 3 is invoked as python3, not python:
python3 -m venv .venvPowerShell refuses to run the activation script
By default, Windows PowerShell blocks unsigned scripts. Enable script execution for the current user:
Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUserThen run the activation script again.
Packages installed but import fails
You likely forgot to activate the environment. Run:
source .venv/bin/activateThen try the import again. You can confirm which Python is active with which python (macOS/Linux) or where python (Windows).
The environment references a deleted Python installation
If you upgrade Python and remove the old version, venv links break. Simply recreate the environment:
rm -rf .venv
python -m venv .venv
source .venv/bin/activate
pip install -r requirements.txtQuick-reference table
| Task | Command |
|---|---|
| Create environment | python -m venv .venv |
| Activate (macOS/Linux) | source .venv/bin/activate |
| Activate (Windows CMD) | .venv\Scripts\activate.bat |
| Activate (Windows PS) | .venv\Scripts\Activate.ps1 |
| Deactivate | deactivate |
| Install a package | pip install requests |
| List installed packages | pip list |
| Export dependencies | pip freeze > requirements.txt |
| Restore dependencies | pip install -r requirements.txt |
| Delete environment | rm -rf .venv |
Related chapters
- Python pip — the full guide to installing, upgrading, and removing packages
- Python Modules — understand how Python's import system works
- Python Packages — organise your own code into installable packages