Tools

Python Virtual Environments with venv: Create, Activate, Freeze and Fix

Tools · · Published 2026-10-30

A virtual environment is a folder that contains its own Python interpreter link and its own site-packages, so each project gets the packages and versions it needs without touching the system Python or other projects. Create one with python -m venv .venv, activate it, install with python -m pip install, record the result with pip freeze, and delete the folder whenever you want a clean start.

The venv module ships with Python 3, so there is nothing to install. The examples below were run with Python 3.13 on Linux; the commands are the same on macOS, and Windows differences are shown where they matter.

Why bother with a virtual environment

Create the environment

Run this from the root of your project. The last argument is the directory to create; .venv is the most common name, and many tools (including VS Code and PyCharm) detect it automatically.

cd my-project
python3 -m venv .venv

On Windows, use the Python launcher so you get the version you expect:

py -m venv .venv

The environment is tied to the interpreter that created it. To build one for a specific version, call that interpreter explicitly, for example python3.12 -m venv .venv or py -3.12 -m venv .venv. If you are not sure which version that is, our guide to checking the Python version shows several ways to find out.

What gets created:

.venv/
├── .gitignore        (Python 3.13+: ignores the whole folder)
├── bin/              (Scripts\ on Windows): python, pip, activate scripts
├── include/
├── lib/python3.13/site-packages/
└── pyvenv.cfg

pyvenv.cfg records the base interpreter. In our test it contained:

home = /usr/bin
include-system-site-packages = false
version = 3.13.17
executable = /usr/bin/python3.13

Activate and deactivate

Activation puts the environment's bin (or Scripts) directory first on your PATH, so python and pip refer to the environment's copies. It also prefixes your prompt with the environment name.

# Linux and macOS (bash, zsh)
source .venv/bin/activate

# Windows, Command Prompt
.venv\Scripts\activate.bat

# Windows, PowerShell
.venv\Scripts\Activate.ps1

# any platform, when you are done
deactivate

If PowerShell refuses to run the script because of its execution policy, the venv documentation suggests allowing signed and local scripts for your user only:

Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser

Activation is a convenience, not a requirement. Calling the environment's interpreter by its path works without it, which is what you want in scripts, cron jobs and Dockerfiles:

.venv/bin/python -m pip install requests
.venv/bin/python manage.py runserver

Check that you are really inside it

Inside a virtual environment, sys.prefix points to the environment while sys.base_prefix still points to the base installation. Comparing them is the reliable test:

import sys

print(sys.executable)
print(sys.prefix != sys.base_prefix)
/home/me/my-project/.venv/bin/python
True

Outside any environment the second line prints False. On the command line, python -m pip --version shows the path pip is installing into, which catches the classic mistake of running a pip that belongs to another interpreter.

Install, freeze and reinstall packages

Prefer python -m pip to a bare pip: it guarantees that pip runs with the interpreter you just named.

python -m pip install requests
python -m pip freeze
certifi==2026.10.23
charset-normalizer==3.5.2
idna==3.20
requests==2.32.3
urllib3==2.8.0

Your version numbers will differ. pip freeze lists every installed distribution with an exact version, including dependencies you never asked for directly. Save it, commit it, and rebuild the same environment elsewhere:

python -m pip freeze > requirements.txt

# on another machine, after creating and activating a fresh .venv
python -m pip install -r requirements.txt

For a library, or when you want looser constraints, keep a short hand-written list of direct dependencies (in requirements.in or the dependencies table of pyproject.toml) and use the frozen file only for exact deployments. To see what a single package resolved to, see checking a package version with pip.

Keep it out of version control

Commit requirements.txt or pyproject.toml, never the environment itself: it contains absolute paths and platform-specific binaries. Since Python 3.13, venv writes a .gitignore containing * inside the new directory, so Git ignores it automatically; pass --without-scm-ignore-files to skip that. With older versions, add .venv/ to your project's .gitignore yourself.

Useful options

An environment cannot simply be moved or renamed, because scripts inside it contain absolute paths. If you move a project, delete .venv and create it again.

Use it in Jupyter and PyCharm

A notebook server does not automatically use your project environment. Register the environment as a kernel from inside it:

python -m pip install ipykernel
python -m ipykernel install --user --name my-project --display-name "Python (my-project)"

Then pick "Python (my-project)" in the kernel menu. In PyCharm, choose the existing .venv/bin/python (or .venv\Scripts\python.exe) as the project interpreter; our guide to installing Python packages in PyCharm walks through the dialogs.

Fixing "error: externally-managed-environment"

Running pip install against a system Python on recent Debian, Ubuntu, Fedora or Homebrew installations often fails with error: externally-managed-environment. This comes from PEP 668: the distribution marks its Python as managed by the operating system's package manager, and pip refuses to modify it. The fix is not --break-system-packages; it is to do exactly what this article describes:

python3 -m venv .venv
.venv/bin/python -m pip install the-package

If python3 -m venv itself fails on Debian or Ubuntu with a message about ensurepip, install the distribution's venv package (for example python3-venv, or the version-specific python3.X-venv) and try again. For command-line applications you want available everywhere, a tool such as pipx creates one isolated environment per application for you.

Troubleshooting

Summary

One project, one .venv: create it with python -m venv .venv, activate it or call .venv/bin/python directly, install with python -m pip, record versions with pip freeze > requirements.txt, keep the folder out of Git, and rebuild it rather than repair it.

Sources

Read next

More in Tools