How to Create and Activate a Python Virtual Environment
Create, activate and deactivate a Python venv on Windows, macOS and Linux, install packages, use requirements.txt, and fix the usual mistakes.
To create a Python virtual environment, go to your project folder and run python3 -m venv .venv on macOS and Linux, or py -m venv .venv on Windows. Then activate it with source .venv/bin/activate (macOS/Linux) or .venv\Scripts\activate (Windows). Your prompt changes, and pip now installs into that project only.
When you're done, type deactivate. That's the whole loop. The rest of this page covers each shell's activation command, installing packages, requirements files, picking a specific Python version, and the mistakes that cause most "virtual environment not working" searches.
Create a Python virtual environment#
The venv module ships with Python's standard library. It builds a lightweight environment with its own set of installed packages, on top of an existing Python installation (the "base" Python). By default it's isolated from the packages in that base installation.
From your project directory:
# macOS and Linux
python3 -m venv .venv
# Windows
py -m venv .venv
The last argument is the folder to create. The Python docs say the folder is conventionally named .venv or venv inside the project, and the packaging guide uses .venv. I'd stick with .venv: it's the one most tools and .gitignore templates expect.
Two habits worth building right away:
- Keep the environment out of Git. Add
.venv/to your.gitignore. - Treat it as disposable. You should be able to delete the folder and rebuild it from a requirements file. Don't put your project code inside it.
Activate a Python virtual environment#
Activating prepends the environment's bin folder (Scripts on Windows) to your PATH. After that, python and pip resolve to the environment's copies.
The activation command depends on your OS and shell:
| Platform | Shell | Command |
|---|---|---|
| macOS / Linux | bash, zsh | source .venv/bin/activate |
| macOS / Linux | fish | source .venv/bin/activate.fish |
| macOS / Linux | csh, tcsh | source .venv/bin/activate.csh |
| macOS / Linux | PowerShell (pwsh) | .venv/bin/Activate.ps1 |
| Windows | cmd.exe | .venv\Scripts\activate.bat |
| Windows | PowerShell | .venv\Scripts\Activate.ps1 |
The packaging guide also shows plain .venv\Scripts\activate for Windows, which works for the default shell setup.
Confirm it worked by checking which interpreter you're getting:
# macOS and Linux
which python
# Windows
where python
The path should end in .venv/bin/python (or .venv\Scripts\python on Windows). If it points anywhere else, the environment isn't active.
You can also ask Python itself. Inside a virtual environment, sys.prefix points at the environment while sys.base_prefix points at the base Python. The docs say comparing them is enough to tell:
import sys
print("prefix: ", sys.prefix)
print("base_prefix:", sys.base_prefix)
print("in a venv? ", sys.prefix != sys.base_prefix)
Run it once with the environment active and once without. The last line should flip.
Activation isn't strictly required#
You can skip activation and call the environment's interpreter by its full path, for example .venv/bin/python script.py or .venv\Scripts\python script.py. Scripts installed into the environment have a shebang line pointing at that interpreter, so they should run without activation too. This is handy in cron jobs, CI steps and editor settings that ask for an interpreter path.
Deactivate and exit a virtual environment#
Type this in the same shell:
deactivate
That works on every platform. Closing the shell also deactivates it. To come back later, run the same activation command again. You don't create a new environment.
One gotcha: the docs say VIRTUAL_ENV gets set when you activate, but since activation is optional, you can't rely on that variable to tell whether an environment is in use. Use the sys.prefix check above instead.
Install packages in your virtual environment#
With the environment active, pip installs into it. I prefer calling pip through Python, as the packaging guide does, because it guarantees you're using the pip that belongs to the interpreter you think you're using.
First make sure pip is current:
# macOS and Linux
python3 -m pip install --upgrade pip
python3 -m pip --version
# Windows
py -m pip install --upgrade pip
py -m pip --version
The --version output shows the path pip lives in, which is a quick way to check you're inside .venv. On Linux, the guide notes you may need to install an extra package such as python3-pip if pip is missing.
Now install something:
python3 -m pip install requests
On Windows, swap python3 for py. Once the environment is active, plain python -m pip install requests also works, since python now resolves to the environment's interpreter.
Common variations, all from the packaging guide (use double quotes on Windows):
python3 -m pip install 'requests==2.18.4' # exact version
python3 -m pip install 'requests>=2.0.0,<3.0.0' # latest 2.x
python3 -m pip install --upgrade requests # upgrade in place
python3 -m pip install --pre requests # allow pre-releases
python3 -m pip install 'requests[security]' # optional extras
python3 -m pip install --editable . # your own project, in development mode
Quote the version specifiers. Without quotes, characters like > and < are treated by your shell as redirection, not as part of the package spec.
Use a requirements file#
A requirements file lists the packages a project needs, so anyone can rebuild the environment. Create requirements.txt:
requests==2.18.4
google-auth==1.1.0
Then install everything in it:
python3 -m pip install -r requirements.txt
To generate a file from what's currently installed, use freeze:
python3 -m pip freeze
It prints every installed package with its exact version, in the same name==version format. Redirect it into a file with python3 -m pip freeze > requirements.txt if you want to save it. Keep in mind that freeze lists transitive dependencies too, so the file can get long. That's fine for reproducing an environment, and it's why a fresh clone can rebuild from it in two commands:
python3 -m venv .venv
.venv/bin/python -m pip install -r requirements.txt
The second line uses the environment's interpreter directly, so it works whether or not you've activated.
This is also your answer to the "can I move or copy a venv?" question. You can't, reliably. Scripts inside an environment contain absolute paths to its interpreter, so the docs say to recreate the environment at the new location and delete the old one. If you rename or move a parent folder, do the same.
Here's a tiny check you can run to see how a requirements line splits into a name and a pinned version:
lines = ["requests==2.18.4", "google-auth==1.1.0"]
for line in lines:
name, version = line.split("==")
print(f"{name:12} pinned to {version}")
Create a virtual environment with a specific Python version#
venv uses the Python that runs it. So the version of the environment is the version of the interpreter you invoke. If you have several versions installed, call the one you want:
python3.12 -m venv .venv
The docs note that on POSIX systems, when you use a specific executable like python3.x, the environment gets python and python3 links pointing at that executable. After activating, python --version tells you what you ended up with.
The venv module can't install a Python version that isn't on your machine. Install that version first, then point -m venv at it.
Common mistakes and fixes#
Most "python virtual environment not working" problems come down to a handful of causes.
Activation does nothing, or the command isn't found. You probably used the wrong script for your shell. Check the table above: activate.bat is for cmd.exe, Activate.ps1 for PowerShell, and source .../activate for bash and zsh. Also check the path. On Windows the folder is Scripts, and on macOS/Linux it's bin. Running .venv/bin/activate without source on Linux won't change your current shell.
pip install puts packages in the wrong place. The environment wasn't active, so you used the base Python's pip. Run python -m pip --version and look at the path. If it doesn't include .venv, activate first, or call .venv/bin/python -m pip install ... (.venv\Scripts\python -m pip install ... on Windows) directly.
deactivate isn't found. That command only exists inside a shell where you activated an environment. A new terminal window doesn't have it. The docs describe the mechanism as platform-specific (typically a script or shell function), so a shell that never ran the activation script won't know it.
The environment broke after you moved or renamed the folder. Because of the absolute paths baked into installed scripts, environments aren't portable. Delete .venv and recreate it from requirements.txt.
You committed .venv to Git. Remove it from the repo and add .venv/ to .gitignore. Environments shouldn't be checked in.
Your editor doesn't see the packages. The editor is using a different interpreter than the one in .venv. Select the interpreter at .venv/bin/python (or .venv\Scripts\python.exe on Windows) in your editor's interpreter setting. The same applies to any tool that asks which Python to run.
Upgrading Python broke the environment. If the base Python was upgraded in place, the builder API has an upgrade option for that case. Often the simpler move is to delete the folder and recreate it.
You want a clean start. Rebuild instead of repairing: delete .venv, run the create command again, then pip install -r requirements.txt.
Quick reference#
| Task | macOS / Linux | Windows |
|---|---|---|
| Create | python3 -m venv .venv |
py -m venv .venv |
| Activate | source .venv/bin/activate |
.venv\Scripts\activate |
| Check interpreter | which python |
where python |
| Upgrade pip | python3 -m pip install --upgrade pip |
py -m pip install --upgrade pip |
| Install a package | python3 -m pip install requests |
py -m pip install requests |
| Install from file | python3 -m pip install -r requirements.txt |
py -m pip install -r requirements.txt |
| Save versions | python3 -m pip freeze |
py -m pip freeze |
| Leave | deactivate |
deactivate |
Checklist before you start coding:
- The environment lives in
.venvinside the project. .venv/is in.gitignore.which pythonorwhere pythonpoints inside.venv.- Dependencies are recorded in
requirements.txt. - You can delete and rebuild the environment without losing anything.
For the full details, see the venv module documentation and the packaging guide on pip and virtual environments.
Quick answers
How do I deactivate or exit a Python virtual environment?
Type deactivate in the same shell where you activated it. It works the same on Windows, macOS and Linux. Closing the shell also leaves the environment.
Why is my Python virtual environment activate command not working?
Usually the script doesn't match your shell or OS. Use source .venv/bin/activate for bash and zsh, .venv\Scripts\activate.bat for cmd.exe, and .venv\Scripts\Activate.ps1 for PowerShell. Then run which python or where python to confirm.
Do I have to activate a virtual environment to use it?
No. You can run the environment's interpreter by its full path, such as .venv/bin/python script.py. Scripts installed into it also have a shebang pointing at that interpreter.
Can I copy or move a virtual environment to another folder?
Not reliably. Installed scripts contain absolute paths to the environment's interpreter. Recreate the environment in the new location and reinstall with pip install -r requirements.txt.
Did this solve it?
One tap. No account.
Sorry about that. What was missing?
from 0 readers
Saved you an hour? Send a tip.
USDC or ETH on Base. Keeps the notes free and the examples running.

0x9dFD2Ee86182f92464b50809C6702B999a0Cd54f
On a computer? Scan the code with your phone wallet, or copy the address.
USDC or ETH on Base works best. Other tokens on Base, Ethereum or Arbitrum also reach this address. Tips are optional and unlock nothing; every guide stays free.
Discussion
Start the discussion
Next note