Create a virtual environment with python -m venv .venv, then activate it with .venv\Scripts\activate on Windows or source .venv/bin/activate on macOS and Linux. Packages you install with pip after that go into the .venv folder for this project only, instead of into your system Python.
Type deactivate to leave it. Everything below explains each step, the PowerShell error almost everyone hits once, and how to share the environment with requirements.txt.
Why use a virtual environment
Without one, every pip install goes into the same Python installation, so two projects that need different versions of the same library break each other. A virtual environment is a folder with its own python, its own pip and its own site-packages. It is cheap: the Python docs describe it as disposable, something you should be able to "delete and recreate from scratch". On many Linux distributions and on Homebrew's Python, pip now refuses system-wide installs entirely, which makes a venv the default rather than an option (see fixing "externally-managed-environment").
How to create a venv
From your project folder:
python -m venv .venv
On macOS and most Linux systems the command is python3; on Windows you can also use the launcher, py -m venv .venv. .venv is just the folder name; it is a common convention, and a leading dot hides the folder in most file listings on macOS and Linux.
The folder layout differs by OS. On Windows with Python 3.12, the test machine produced:
.venv\
Include\
Lib\
Scripts\ activate, activate.bat, Activate.ps1, deactivate.bat, pip.exe, python.exe ...
pyvenv.cfg
On macOS and Linux, Scripts is called bin and Lib is lib. pyvenv.cfg records which Python created the environment:
home = C:\Program Files\Python312
include-system-site-packages = false
version = 3.12.2
How to activate a venv on each OS and shell
| Shell | Command |
|---|---|
| Windows Command Prompt (cmd) | .venv\Scripts\activate.bat |
| Windows PowerShell | .venv\Scripts\Activate.ps1 |
| Git Bash on Windows | source .venv/Scripts/activate |
| macOS / Linux (bash, zsh) | source .venv/bin/activate |
| fish | source .venv/bin/activate.fish |
| csh / tcsh | source .venv/bin/activate.csh |
When it works, your prompt starts with (.venv), and python now means the environment's interpreter. Check it:
python -c "import sys; print(sys.prefix != sys.base_prefix, sys.prefix)"
Example output on Windows:
True C:\Users\you\project\.venv
pip --version also shows the path, for example pip 24.0 from C:\Users\you\project\.venv\Lib\site-packages\pip (python 3.12). If it shows a path outside .venv, activation didn't take effect in this terminal.
PowerShell: "running scripts is disabled on this system"
On Windows, PowerShell refuses to run Activate.ps1 when its execution policy is Restricted, the default for Windows client editions. This is the real error:
File C:\Users\you\project\.venv\Scripts\Activate.ps1 cannot be loaded because running
scripts is disabled on this system. For more information, see about_Execution_Policies
at https:/go.microsoft.com/fwlink/?LinkID=135170.
+ CategoryInfo : SecurityError: (:) [], PSSecurityException
+ FullyQualifiedErrorId : UnauthorizedAccess
The fix the Python docs give is to allow local scripts for your user account only:
Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser
RemoteSigned runs scripts created on your machine and still requires a signature on scripts downloaded from the internet. -Scope CurrentUser affects only your account; Microsoft's docs say administrator rights are needed only for the LocalMachine scope. Check the result with Get-ExecutionPolicy -List.
If you'd rather not change the policy at all, two alternatives work: use Command Prompt and activate.bat, or skip activation and call the interpreter directly (next section).
Using a venv without activating it
Activation only edits your PATH for the current terminal. The Python docs say you don't "specifically need" it, because you can run the environment's interpreter by path:
# Windows
.venv\Scripts\python.exe -m pip install requests
.venv\Scripts\python.exe app.py
# macOS / Linux
.venv/bin/python -m pip install requests
.venv/bin/python app.py
This is the most reliable form for scripts, scheduled tasks and CI jobs, where there is no interactive shell to activate.
How to deactivate
deactivate
The same command works in every shell. Closing the terminal has the same effect, since activation never changes anything outside that session.
Saving and restoring packages with requirements.txt
With the environment active, record exactly what is installed:
python -m pip freeze > requirements.txt
Each line pins a version, such as requests==2.32.3. On another machine, or after deleting the folder, recreate the environment and install the same versions:
python -m venv .venv
# activate it, then:
python -m pip install -r requirements.txt
The pip docs show the same commands with py -m pip for Windows. Using python -m pip rather than bare pip guarantees that pip runs for the interpreter you think it does.
Why you should not commit the venv folder
The Python docs list three properties of a virtual environment: it is "not checked into source control systems such as Git", it is disposable, and it is "not considered as movable or copyable". The folder holds absolute paths to the Python that created it and compiled files for one OS, so a copy on a colleague's machine won't work anyway. Commit requirements.txt (or your project's lock file) instead.
Since Python 3.13, venv writes a .gitignore inside the new folder that tells Git to ignore the whole environment. On older versions (the 3.12 test environment had no such file), add the line yourself to the project's .gitignore:
.venv/
If it still isn't working
- Packages "not found" after installing: you installed with one Python and run with another. Compare
python -m pip --versionwith the interpreter your editor uses, and select.venvas the interpreter in the editor. pythonon Windows opens the Microsoft Store or says "command not found": the Python docs' Windows troubleshooting table says to open Start, search for "Manage app execution aliases", and check the Python aliases there. Until then,py -m venv .venvworks if the launcher is installed.- The environment broke after upgrading Python: delete
.venvand recreate it fromrequirements.txt. That is the intended workflow, not a workaround.
When a script inside the venv crashes, the traceback shows which file each frame comes from, including whether it is your code or a library in .venv; how to read a stack trace walks through it.
Frequently asked questions
- Do I have to activate a virtual environment?
- No. Activation only puts the environment's folder first on your PATH. You can run the environment's interpreter directly instead, for example .venv\Scripts\python.exe app.py on Windows or .venv/bin/python app.py on macOS and Linux, and scripts installed into the environment run correctly without activation.
- Can I move or rename a venv folder?
- Not reliably. The Python docs describe virtual environments as not movable or copyable, because they contain absolute paths to the interpreter. Delete the folder and create a new one in the new location, then reinstall from requirements.txt.
- How do I check whether a virtual environment is active?
- Run python -c "import sys; print(sys.prefix != sys.base_prefix)". It prints True inside a virtual environment. Most shells also show the environment name, such as (.venv), at the start of the prompt.
- What is the difference between venv and virtualenv?
- venv is the module built into Python 3 that creates virtual environments. virtualenv is a separate third-party package that does the same job. For most projects the built-in python -m venv is enough.