Quick Answer

A virtual environment is a private folder holding its own Python interpreter and packages, so each project keeps its own dependency versions instead of sharing one global set. Create one with python -m venv venv, activate it, then install packages with pip as normal. Save the exact versions with pip freeze into requirements.txt so anyone can rebuild the same environment, and add the venv folder to .gitignore rather than committing it.

Why You Need One

Install packages globally and every project on your machine shares them. That works until two projects disagree.

Project A needs Django 3.2
Project B needs Django 5.0

pip install django==5.0    →  Project A now breaks

There is no way to have both globally. This is dependency hell, and it is the reason virtual environments exist rather than being optional polish.

A virtual environment is a directory containing its own interpreter and its own site-packages. Activate it and python and pip point inside that folder, so installs affect only that project. Deactivate and you are back to the system Python.

Three problems this solves at once. Projects stop interfering with each other. You avoid installing into the system Python, which on Linux and macOS can break OS tools that depend on specific versions. And you get an exact, reproducible list of what a project needs — which is what makes "works on my machine" a solvable problem rather than an argument.

Newer Linux distributions now refuse global pip installs outright with an externally-managed-environment error, precisely to force this habit.

Creating and Activating One

venv ships with Python 3, so there is nothing to install.

# From your project folder
python -m venv venv

That creates a venv/ directory. The activation command differs by platform, which is the single most common stumbling block:

# Windows — Command Prompt
venv\Scripts\activate

# Windows — PowerShell
venv\Scripts\Activate.ps1

# macOS / Linux / Git Bash
source venv/bin/activate

When it works, your prompt gains a prefix:

(venv) C:\projects\myapp>

That prefix is the whole confirmation. No prefix means you are not in the environment and pip install is going somewhere global.

To verify properly, ask which interpreter is being used — it should point inside your project:

where python      # Windows
which python      # macOS / Linux

Leave with deactivate. Delete the environment by deleting the folder; there is nothing else to clean up, which is why it is safe to throw one away and rebuild when something goes wrong.

pip and requirements.txt

With the environment active, pip installs into it.

pip install requests
pip install django==4.2        # a specific version
pip list                      # what is installed here
pip show requests             # details and dependencies

To let someone else reproduce your setup, record the exact versions:

pip freeze > requirements.txt

And to rebuild from it:

pip install -r requirements.txt

One habit worth adopting early: pin versions. pip freeze writes requests==2.31.0 rather than requests, so a future install gets the same version you tested against. An unpinned requirements file will one day install a new major release and break the project with no change from you.

Note that pip freeze captures everything installed, including sub-dependencies you never asked for. That is correct for reproducibility but makes the file noisy. Tools like Poetry and pipenv separate what you asked for from what came along with it — worth knowing about, though venv plus pip is entirely sufficient for learning and for most projects.

The Errors You Will Hit

PowerShell blocks activation.

Activate.ps1 cannot be loaded because running scripts is disabled

Windows blocks unsigned scripts by default. Allow local ones for your user:

Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser

"pip is not recognised". Usually Python is not on PATH. Use python -m pip instead of pip — it works whenever python does, and it also guarantees you are using the pip belonging to that interpreter.

ModuleNotFoundError for something you just installed. Almost always the environment is not active, or you installed from a different terminal. Check for the (venv) prefix, then run pip list to confirm the package is in this environment.

Your editor cannot find the packages. VS Code needs to be pointed at the interpreter: Ctrl+Shift+P, "Python: Select Interpreter", choose the one inside venv. Otherwise the terminal works while the editor underlines every import in red.

The environment stops working after moving the folder. Virtual environments contain absolute paths and do not survive being moved or renamed. Delete it and recreate — that is the intended fix, which is also why you should never commit it.

Habits Worth Forming Now

  • One environment per project, created in the project folder, before installing anything.
  • Add it to .gitignore. A venv/ folder is thousands of platform-specific files. Commit requirements.txt instead — it is the recipe, not the meal.
  • Name it consistently, venv or .venv. Editors recognise both automatically.
  • Regenerate requirements.txt after adding a dependency, and commit that change alongside the code that needs it.
  • Never sudo pip install. That writes into the system Python and can break OS tooling. If a global install feels necessary, the answer is a virtual environment.
# .gitignore
venv/
.venv/
__pycache__/
*.pyc
.env

The payoff is that a new machine, a teammate, or a deployment can go from a fresh clone to a working project in two commands. That reproducibility is the entire point, and it is also what interviewers are checking when they ask how you manage dependencies.

Frequently Asked Questions

Do I really need a virtual environment for small projects? Yes, and small projects are where the habit is cheap to build. It costs one command, prevents version conflicts later, and makes requirements.txt meaningful. Many Linux distributions now block global pip installs anyway.
Should I commit the venv folder to git? No. It contains thousands of platform-specific files with absolute paths, so it will not work on another machine. Commit requirements.txt, which lets anyone rebuild an identical environment, and add venv/ to .gitignore.
What is the difference between venv and virtualenv? venv is built into Python 3 and is sufficient for almost everything. virtualenv is an older third-party tool that is somewhat faster and supports older Python versions. For new projects, use venv.
Why does PowerShell refuse to activate my environment? PowerShell blocks unsigned scripts by default. Run Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser to allow local scripts for your user only. Command Prompt does not have this restriction.
Why does Python say a module is missing after I installed it? Usually the environment is not activated, so pip installed elsewhere. Check your prompt shows (venv) and run pip list to confirm. If the terminal works but the editor complains, point your editor at the interpreter inside the venv folder.