Virtual environments with venv
A virtual environment is a private folder of Python packages for one project, so projects never fight over versions. Create one with python -m venv .venv.
When you run pip install requests without a virtual environment, the package lands in a Python installation shared by everything on your machine. Two projects that need different versions of the same library will then break each other. A virtual environment solves this: it is a folder (usually called .venv) that holds its own copy of the Python launcher and its own site-packages directory. Packages installed while it is active go into that folder and nowhere else.
The tool for this, venv, ships with Python itself, so there is nothing extra to install.
Create and activate
Run this once inside your project folder:
python3 -m venv .venv
Then activate it in every new terminal where you work on the project:
# macOS / Linux (bash, zsh)
source .venv/bin/activate
# Windows PowerShell
.venv\Scripts\Activate.ps1
# Windows cmd.exe
.venv\Scripts\activate.bat
Your prompt usually changes to show (.venv). From now on, python and pip point at the environment. Check it any time:
python -c "import sys; print(sys.prefix)"
# should print a path ending in .venv
To leave the environment, run deactivate. Activation is only a convenience that edits your PATH; you can also skip it and call the environment’s interpreter directly, for example .venv/bin/python main.py. That is handy in cron jobs and scripts.
Install packages and record them
python -m pip install requests
python -m pip freeze > requirements.txt
pip freeze writes every installed package with its exact version. Commit requirements.txt to Git so a teammate (or future you) can rebuild the same environment:
python3 -m venv .venv
source .venv/bin/activate
python -m pip install -r requirements.txt
Prefer python -m pip over bare pip. It guarantees that pip installs into the same interpreter you are going to run, which avoids the most common cause of ModuleNotFoundError.
Rules of thumb
- One environment per project, created inside the project folder.
- Never commit
.venv; add.venv/to.gitignore. Environments contain absolute paths and are not portable, so you rebuild them instead of copying them. - If an environment gets messy, delete the folder and create it again from
requirements.txt. It is disposable. - Pick the Python version when you create it:
python3.12 -m venv .venv. The environment keeps using that version. - Point your editor at
.venv(VS Code and PyCharm both detect it) so autocomplete and linting see your packages.
Why pip sometimes refuses to install
On many Linux distributions and on Homebrew’s Python, running pip install outside an environment fails with error: externally-managed-environment. This is deliberate (see PEP 668): the system Python belongs to the operating system’s package manager. Creating a virtual environment is the intended fix, not a workaround.
Faster alternative: uv
uv is a newer tool that creates environments and installs packages much faster and can also download Python versions for you. The concepts are identical, only the commands differ:
uv venv # creates .venv
uv pip install -r requirements.txt
# or let uv manage the whole project
uv init myproject && cd myproject
uv add requests # updates pyproject.toml and uv.lock
uv run main.py # runs inside the project environment
Whichever tool you use, the idea stays the same: every project gets its own isolated set of packages, described in a file you commit, and the environment itself is something you can throw away and rebuild.
See also
- 0007 Fix: ModuleNotFoundError: No module named ‘…’ Python cannot find a module you import. Usually the package was installed into a different interpreter or virtual environment than the one… Beginner · Fix · Any system Article Common errors · Environments & packages 15 Oct 2026
- 0011 Bootstrap a new Python project with a venv A Bash script that creates a project folder with a virtual environment, .gitignore, requirements.txt and a starter main.py, then runs it to… Intermediate · How-to · Linux, macOS Script Environments & packages 15 Oct 2026
- 0261 Build a Python command-line to-do app: from empty folder to installable command Create a small to-do tool in Python with argparse and JSON storage, test it with pytest and package it with pyproject.toml so… Beginner · Tutorial · Any system Article Environments & packages · Files & automation · Testing 15 Oct 2026
Repos in the wild
- uv: Python package and project manager astral-sh/uv uv is a very fast Python package and project manager written in Rust. It replaces pip, venv and related tools, manages lock files and can install Python itself. GitHub
History
Every saved edit is kept. The plot on the sleeve draws one line per edit. Open any edit to see exactly what changed.
- commitpedia-admin +3,549 chars