Skip to content
C Codeloom
Python

Python Virtual Environments Guide

Stop polluting your system Python — a practical guide to virtual environments with venv, activating and deactivating them, requirements.txt, and a quick look at modern alternatives.

·5 min read · By Codeloom
Beginner 9 min read

What you'll learn

  • Why virtual environments exist
  • Creating and activating a venv
  • Installing packages and freezing requirements
  • Recreating an environment from requirements.txt
  • Modern alternatives like uv, poetry, and pipx

Prerequisites

  • Basic Python familiarity

A virtual environment is an isolated Python installation that lives inside a folder in your project. It has its own copy of python, its own pip, and its own site-packages directory. The point is simple: each project gets its own dependencies, and nothing you install for one project leaks into another or into your system Python.

Why You Need One

Without a virtual environment, every pip install modifies the same shared site-packages. That leads to predictable trouble:

  • Project A needs requests==2.20, project B needs requests==2.31. Only one can win.
  • Upgrading a library to fix one project quietly breaks another.
  • Your system package manager installs Python tools too, and pip install can collide with them.
  • Reproducing a colleague’s setup becomes archaeology.

A virtual environment per project sidesteps all of this. Treat it as a hard rule: every project gets its own venv.

Creating a venv

Python ships a built-in module called venv.

python3 -m venv .venv

This creates a .venv directory in the current folder. The leading dot is convention — it hides the folder in most file browsers and signals “tooling, not source code.” The folder contains a Python binary, a copy of pip, and an empty site-packages.

You can pick any name you like, but .venv is the de facto standard and is recognised by most editors automatically.

Activating It

Activating a venv adjusts your shell’s PATH so that python and pip point at the venv’s copies.

On macOS or Linux:

source .venv/bin/activate

On Windows (PowerShell):

.venv\Scripts\Activate.ps1

You will see your prompt change to include (.venv) as a reminder. From now on, pip install puts packages into .venv/lib/.../site-packages and nowhere else.

To leave the venv:

deactivate

Installing Packages

Once activated, install packages exactly as you would normally.

pip install requests
pip install "flask>=3.0"

You can confirm what is installed with pip list or pip show requests. Everything you install affects only this project.

Pinning Dependencies with requirements.txt

To make your environment reproducible — for a teammate, a CI server, or a future you — record the installed versions.

pip freeze > requirements.txt

This writes every installed package with its exact version. Commit the file. To recreate the environment elsewhere:

python3 -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt

That is the entire onboarding ritual for a Python project.

A common refinement is to keep two files: requirements.txt for the direct dependencies you actually want, and requirements.lock.txt for the full pinned set generated from pip freeze. That way upgrades are clear and intentional.

A Tiny Example Project

# app.py
import requests

r = requests.get("https://example.com")
print(r.status_code)

Setup, run, and tear down:

python3 -m venv .venv
source .venv/bin/activate
pip install requests
python app.py
deactivate

That is the whole workflow. The exact same sequence works for every Python project you will ever start.

Editor Integration

Most editors detect a .venv folder automatically and use its interpreter for linting, autocomplete, and type checking. In VS Code, the Python extension shows the active interpreter in the status bar — click it to switch between venvs. In PyCharm, the interpreter is set per project under Settings -> Python Interpreter.

If your editor is using the wrong Python — and you cannot understand why type hints don’t resolve — check that it is pointed at the venv.

Common Mistakes

Installing without activating. Running pip install in a shell where the venv is not active dumps packages into your system Python again. The fix is to always check for (.venv) in your prompt before running pip.

Committing the venv folder. Add .venv/ to .gitignore. Virtual environments are not portable across machines or even Python versions, and they are large. Commit requirements.txt instead and let collaborators rebuild.

Forgetting to upgrade pip. After creating a venv, pip install --upgrade pip is a sensible first step. The pip bundled with venv is often a few releases behind.

Modern Alternatives

The Python packaging world has moved fast. A few tools worth knowing about:

  • uv is a recent Rust-based tool that creates venvs and installs packages dramatically faster than pip. Drop-in compatible for most workflows.
  • poetry manages dependencies, virtual environments, and packaging from a single pyproject.toml. Popular in libraries and serious applications.
  • pipx installs Python applications (not libraries) into their own venvs and exposes their CLIs globally. Great for tools like httpie, ruff, or mypy.
  • conda ships its own environments and is dominant in scientific Python, where binary packages with native dependencies matter.

You don’t need any of these to get started. The built-in venv plus pip handles every project well enough until you have a reason to switch.

A Quick Mental Model

Every Python project should answer two questions on day one: where does its Python live, and where do its packages live. A venv answers both — the binary in .venv/bin/python and the packages in .venv/lib/.../site-packages. Once you have internalised that, nothing about Python environments feels mysterious anymore.

Wrapping Up

Virtual environments take less than thirty seconds to set up and prevent a long list of headaches. Make python3 -m venv .venv the first command you run in every new project, commit a requirements.txt, and your future self will be glad you did.