Virtual environments are essential for Python development. They isolate project dependencies, prevent conflicts, and ensure reproducibility. This guide covers all major tools and helps you choose the right approach for your workflow.
Why Virtual Environments Matter
Without virtual environments, all Python packages install to a single location:
┌─────────────────────────────────────────────────────────────┐
│ Without Virtual Environments │
├─────────────────────────────────────────────────────────────┤
│ │
│ System Python (/usr/bin/python3) │
│ └── site-packages/ │
│ ├── requests 2.31.0 ← Project A needs 2.28! │
│ ├── django 4.2 ← Project B needs 3.2! │
│ └── numpy 1.24 ← Both projects, different needs │
│ │
│ Problem: Only one version of each package can exist │
│ │
└─────────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────┐
│ With Virtual Environments │
├─────────────────────────────────────────────────────────────┤
│ │
│ project-a/.venv/ project-b/.venv/ │
│ └── site-packages/ └── site-packages/ │
│ ├── requests 2.28.0 ├── requests 2.31.0 │
│ ├── django 4.2 ├── django 3.2 │
│ └── numpy 1.23 └── numpy 1.24 │
│ │
│ Solution: Each project has isolated dependencies │
│ │
└─────────────────────────────────────────────────────────────┘
Tool Comparison
| Feature | venv | virtualenv | conda | pyenv |
|---|---|---|---|---|
| Built into Python | Yes (3.3+) | No | No | No |
| Python version management | No | No | Yes | Yes |
| Non-Python packages | No | No | Yes | No |
| Speed | Fast | Faster | Slow | Fast |
| Best for | Most projects | Legacy | Data science | Multi-version |
venv: The Standard Tool
venv is Python's built-in virtual environment module. Use it for most projects.
Creating a Virtual Environment
# Create environment in .venv folder
python -m venv .venv
# Or with a descriptive name
python -m venv venv
# Create with specific Python (if you have multiple)
python3.11 -m venv .venv
Activating and Deactivating
# macOS/Linux
source .venv/bin/activate
# Windows (Command Prompt)
.venv\Scripts\activate.bat
# Windows (PowerShell)
.venv\Scripts\Activate.ps1
# Your prompt shows the active environment
(.venv) $
# Deactivate when done
deactivate
Installing Packages
# Activate first, then install
source .venv/bin/activate
pip install requests flask pytest
# Install from requirements file
pip install -r requirements.txt
# Verify isolation (package only in .venv)
which python # /path/to/project/.venv/bin/python
venv Options
# Include system site-packages (not recommended)
python -m venv --system-site-packages .venv
# Create without pip (lighter, add pip later)
python -m venv --without-pip .venv
# Clear existing environment and recreate
python -m venv --clear .venv
# Upgrade embedded pip to latest
python -m venv --upgrade-deps .venv
What's Inside .venv?
.venv/
├── bin/ # macOS/Linux executables
│ ├── activate # Activation script
│ ├── pip # Environment's pip
│ ├── python # Symlink to Python
│ └── python3 # Another symlink
├── include/ # C headers for building packages
├── lib/
│ └── python3.11/
│ └── site-packages/ # Installed packages go here
└── pyvenv.cfg # Environment configuration
virtualenv: Extended Features
virtualenv is a third-party tool with features beyond venv.
Installation
pip install virtualenv
Creating Environments
# Basic creation (same as venv)
virtualenv .venv
# Specify Python version
virtualenv -p python3.11 .venv
# Use a specific Python binary
virtualenv -p /usr/local/bin/python3.12 .venv
virtualenv Advantages
# Faster creation (caches packages)
virtualenv .venv # Creates much faster than venv
# Better cross-platform support
# More reliable on older systems
# Relocatable environments (advanced)
virtualenv --relocatable .venv
When to Use virtualenv Over venv
- You need to support Python 2 (legacy projects)
- You create many environments and need speed
- You need advanced features like
--relocatable - Your system's venv has bugs (rare)
For most modern projects, venv is sufficient.
conda: Beyond Python
Conda manages packages AND environments, handling non-Python dependencies.
Installing conda
# Miniconda (minimal, recommended)
# Download from https://docs.conda.io/en/latest/miniconda.html
# Or Anaconda (full data science distribution)
# Download from https://www.anaconda.com/download
# Verify installation
conda --version
Creating Environments
# Create with specific Python version
conda create -n myproject python=3.11
# Create with packages
conda create -n datascience python=3.11 numpy pandas matplotlib
# Create from environment file
conda env create -f environment.yml
Activating Environments
# Activate
conda activate myproject
# Deactivate
conda deactivate
# List all environments
conda env list
Installing Packages
# Prefer conda install for scientific packages
conda install numpy scipy pandas
# Specific versions
conda install numpy=1.24
# From conda-forge channel (more packages)
conda install -c conda-forge package-name
# Use pip for packages not in conda
pip install package-not-in-conda
Environment Files
# environment.yml
name: myproject
channels:
- conda-forge
- defaults
dependencies:
- python=3.11
- numpy>=1.24
- pandas>=2.0
- scikit-learn
- pip
- pip:
- some-pip-only-package
# Create from file
conda env create -f environment.yml
# Update existing environment
conda env update -f environment.yml
# Export current environment
conda env export > environment.yml
# Export without build numbers (more portable)
conda env export --no-builds > environment.yml
When to Use conda
- Data science and scientific computing
- Packages with complex C/C++ dependencies
- Need specific binary packages (CUDA, MKL)
- Cross-platform binary reproducibility
- Team uses Anaconda distribution
conda vs pip
| Use Case | Prefer |
|---|---|
| numpy, pandas, scikit-learn | conda |
| Web frameworks (Django, Flask) | pip |
| Binary packages (OpenCV, PyTorch) | conda |
| Pure Python packages | pip |
| Packages not in conda | pip |
pyenv: Multiple Python Versions
pyenv manages Python installations—different from creating environments.
Installing pyenv
# macOS with Homebrew
brew install pyenv
# Linux (automatic installer)
curl https://pyenv.run | bash
# Add to shell (bash)
echo 'export PYENV_ROOT="$HOME/.pyenv"' >> ~/.bashrc
echo 'command -v pyenv >/dev/null || export PATH="$PYENV_ROOT/bin:$PATH"' >> ~/.bashrc
echo 'eval "$(pyenv init -)"' >> ~/.bashrc
# Add to shell (zsh)
echo 'export PYENV_ROOT="$HOME/.pyenv"' >> ~/.zshrc
echo 'command -v pyenv >/dev/null || export PATH="$PYENV_ROOT/bin:$PATH"' >> ~/.zshrc
echo 'eval "$(pyenv init -)"' >> ~/.zshrc
Installing Python Versions
# List available versions
pyenv install --list
# Install specific versions
pyenv install 3.11.7
pyenv install 3.12.1
# List installed versions
pyenv versions
Switching Versions
# Set global default
pyenv global 3.11.7
# Set for current directory (creates .python-version file)
pyenv local 3.12.1
# Set for current shell session only
pyenv shell 3.10.13
# Check current version
pyenv version
python --version
Using pyenv with venv
# Set Python version for project
cd my-project
pyenv local 3.11.7
# Create venv with that version
python -m venv .venv
# Now .venv uses Python 3.11.7
source .venv/bin/activate
python --version # Python 3.11.7
pyenv-virtualenv Plugin
Combines pyenv and virtualenv:
# Install plugin
brew install pyenv-virtualenv # macOS
# Or manually
git clone https://github.com/pyenv/pyenv-virtualenv.git \
$(pyenv root)/plugins/pyenv-virtualenv
# Create virtualenv with specific Python
pyenv virtualenv 3.11.7 myproject-env
# Activate
pyenv activate myproject-env
# Auto-activate in directory
pyenv local myproject-env
IDE Integration
VS Code
VS Code automatically detects .venv folders.
// .vscode/settings.json
{
"python.defaultInterpreterPath": "${workspaceFolder}/.venv/bin/python",
"python.terminal.activateEnvironment": true
}
Select interpreter: Cmd/Ctrl + Shift + P → "Python: Select Interpreter"
PyCharm
- File → Settings → Project → Python Interpreter
- Click gear icon → Add
- Choose "Existing environment" and browse to
.venv/bin/python
Or let PyCharm create the environment:
- Click gear icon → Add
- Choose "New environment"
- Select "Virtualenv" or "Conda"
Jupyter Notebooks
# Install ipykernel in your environment
source .venv/bin/activate
pip install ipykernel
# Register the environment as a Jupyter kernel
python -m ipykernel install --user --name=myproject
# Now "myproject" appears as a kernel option in Jupyter
Best Practices
1. One Environment Per Project
project-a/
├── .venv/ # Project A's environment
├── requirements.txt
└── src/
project-b/
├── .venv/ # Project B's environment
├── requirements.txt
└── src/
2. Use .venv as the Name
It's the convention, automatically recognized by tools:
# Standard location
python -m venv .venv
# Ignored by most .gitignore templates
# Recognized by VS Code, PyCharm, etc.
3. Never Commit the Environment
# .gitignore
.venv/
venv/
env/
.env/
Share requirements.txt instead:
# Export dependencies
pip freeze > requirements.txt
# Or better, use pip-compile
pip-compile requirements.in
4. Always Activate Before Installing
# WRONG: Installs to global Python
pip install requests
# RIGHT: Activate first
source .venv/bin/activate
pip install requests
5. Use requirements.txt for Reproducibility
# Create environment
python -m venv .venv
source .venv/bin/activate
# Install dependencies
pip install -r requirements.txt
# Verify
pip list
6. Document the Python Version
# README.md
## Requirements
- Python 3.11+
## Setup
```bash
python -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt
Or use `.python-version` with pyenv:
.python-version
3.11.7
## Common Issues and Solutions
### "Command not found: activate"
```bash
# Wrong
activate
# Correct (must use source)
source .venv/bin/activate
Package Not Found After Install
# Check you're in the right environment
which python
# Should show: /path/to/project/.venv/bin/python
# Not: /usr/bin/python or /usr/local/bin/python
Permission Denied on Windows
# Enable script execution
Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser
# Then activate
.venv\Scripts\Activate.ps1
Environment Doesn't Match requirements.txt
# Recreate from scratch
rm -rf .venv
python -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt
Different Python Than Expected
# Specify Python explicitly
/usr/local/bin/python3.11 -m venv .venv
# Or use pyenv
pyenv local 3.11.7
python -m venv .venv
Quick Reference
venv Commands
python -m venv .venv # Create
source .venv/bin/activate # Activate (Unix)
.venv\Scripts\activate # Activate (Windows)
deactivate # Deactivate
rm -rf .venv # Delete
conda Commands
conda create -n name python=3.11 # Create
conda activate name # Activate
conda deactivate # Deactivate
conda env list # List environments
conda env remove -n name # Delete
conda env export > env.yml # Export
pyenv Commands
pyenv install 3.11.7 # Install Python
pyenv versions # List installed
pyenv global 3.11.7 # Set default
pyenv local 3.11.7 # Set for directory
pyenv shell 3.11.7 # Set for session
Next Steps
- Learn dependency management in our Dependency Management Tools Guide
- See our requirements.txt Guide for dependency files
- Explore the Python Packaging Complete Guide for the full ecosystem
For more Python development guides, explore our complete Python packaging series.