How-to guide

Python Virtual Environments with uv

Comprehensive guide to creating and managing Python virtual environments using uv, a fast and modern Python package manager.


Authors

Last Modified

  • October 15, 2026

License

What is uv?

uv is a fast Python package installer and resolver written in Rust. It serves as a drop-in replacement for pip and pip-tools, while also providing unified project management capabilities.

Why use uv?

  • Speed: Fast package installation and resolution
  • Simplicity: Single tool for managing Python versions, virtual environments, and packages
  • Modern workflow: Built-in support for pyproject.toml and modern Python packaging standards
  • Reliability: Deterministic dependency resolution and lockfiles
  • Compatibility: Works with existing pip and requirements.txt workflows

uv vs Other Tools

Feature uv pip conda
Speed Extremely fast (Rust-based) Moderate Slow to moderate
Virtual environments Built-in (uv venv) Requires separate venv module Built-in
Dependency resolution Advanced, deterministic Basic Advanced
Python version management Yes No Yes
Non-Python packages No No Yes
Best for Python-only projects, modern workflows Simple projects, compatibility Multi-language scientific computing

For Python-only or Python-plus-Stata research and data science projects, uv provides the best balance of speed, simplicity, and modern features.

Installing uv

Installation by Platform

# Install uv using winget
winget install astral-sh.uv
# Install uv using Homebrew
brew install uv
# Install uv using Homebrew
brew install uv

Or use the standalone installer:

# Install using the official installer script
curl -LsSf https://astral.sh/uv/install.sh | sh

Verify Installation

After installation, verify that uv is available:

# Check uv version
uv --version

You should see output like uv 0.x.x indicating the installed version.

Creating Virtual Environments

Basic Environment Creation

Create a virtual environment in the current directory:

# Create a virtual environment named .venv
uv venv

This creates a .venv directory containing the isolated Python environment.

Custom Environment Names

Specify a custom name for your environment:

# Create environment with custom name
uv venv myproject-env

Specifying Python Version

Create an environment with a specific Python version:

# Create environment with Python 3.11
uv venv --python 3.12

# Or specify the full version
uv venv --python 3.12.5

If the specified Python version is not installed, uv will automatically download and install it.

Activating Virtual Environments

After creating an environment, activate it to use it:

On Windows:

# Powershell
.venv\Scripts\activate

# NuShell
overlay using .venv/Scripts/activate.nu

On macOS/Linux:

# bash
source .venv/bin/activate

# NuShell
overlay using .venv/Scripts/activate.nu

When activated, your command prompt will show the environment name, typically as (.venv) or (myproject-env).

Deactivating Environments

To exit the virtual environment:

# Deactivate the current environment
deactivate

Managing Packages

Installing Packages

uv provides multiple ways to install packages:

Using uv pip

Drop-in replacement for pip:

# Install a single package
uv pip install pandas

# Install multiple packages
uv pip install pandas numpy matplotlib seaborn

# Install with specific version
uv pip install pandas==2.0.0

# Install from requirements.txt
uv pip install -r requirements.txt

Using uv add (Project Mode)

For project-based workflows with pyproject.toml:

# Add package to project dependencies
uv add pandas

# Add multiple packages
uv add pandas numpy matplotlib seaborn jupyterlab

# Add development dependencies
uv add --dev pytest ruff black

This command:

  1. Installs the package in the active environment
  2. Adds it to pyproject.toml dependencies
  3. Updates the lockfile for reproducibility

Upgrading Packages

Update packages to the latest versions:

# Upgrade a specific package
uv pip install --upgrade pandas

# Upgrade all packages in requirements.txt
uv pip install --upgrade -r requirements.txt

Listing Installed Packages

View packages in the current environment:

# List all installed packages
uv pip list

# Show package details
uv pip show pandas

Uninstalling Packages

Remove packages from the environment:

# Uninstall a package
uv pip uninstall pandas

# Uninstall multiple packages
uv pip uninstall pandas numpy

Working with pyproject.toml

pyproject.toml is the modern standard for Python project configuration. uv integrates seamlessly with it.

Basic Project Structure

[project]
name = "my-research-project"
version = "0.1.0"
description = "Analysis of survey data"
requires-python = ">=3.10"
dependencies = [
    "pandas>=2.0.0",
    "numpy>=1.24.0",
    "matplotlib>=3.7.0",
    "seaborn>=0.12.0",
]

[dependency-groups]
dev = [
    "pytest>=7.0.0",
    "ruff>=0.1.0",
    "jupyterlab>=4.0.0",
]

Creating a New Project

Initialize a new project with uv:

# Create a new project directory and pyproject.toml
uv init my-project
cd my-project

This creates a basic project structure with pyproject.toml.

Installing from pyproject.toml

Install all dependencies defined in pyproject.toml:

# Install project dependencies
uv sync

# Install with optional dependency groups
uv sync --extra dev

Adding Dependencies

Add packages and automatically update pyproject.toml:

# Add to main dependencies
uv add pandas numpy

# Add to development dependencies
uv add --dev pytest ruff

Lockfiles for Reproducibility

uv creates uv.lock to pin exact versions:

# Generate/update lockfile
uv lock

# Install from lockfile (exact versions)
uv sync

Commit uv.lock to version control to ensure everyone uses identical package versions.

Common Workflows

Starting a New Project

Complete workflow for a new research project:

# Create project directory
mkdir my-analysis
cd my-analysis

# Initialize uv project
uv init

# Create virtual environment
uv venv

# Activate environment (Windows PowerShell)
.venv\Scripts\activate

# Activate environment (NuShell)
# overlay using .venv\Scripts\activate.nu

# Activate environment (bash)
# source .venv/bin/activate

# Add dependencies
uv add pandas numpy matplotlib seaborn jupyterlab

# Add development tools
uv add --dev pytest ruff

# Start working
jupyter lab
# or uv run jupyter lab

Cloning an Existing Project

Set up an environment from a project with pyproject.toml:

# Clone the repository
git clone https://github.com/organization/project.git
cd project

# Create virtual environment
uv venv

# Activate environment
.venv\Scripts\activate # or source .venv/bin/activate  in bash

# Install all dependencies from lockfile
uv sync

Updating Dependencies

Keep project dependencies current:

# Update all dependencies to latest compatible versions
uv lock --upgrade

# Update specific package
uv lock --upgrade-package pandas

# Install updated dependencies
uv sync

Sharing Environments

For collaborators not using uv:

# Export to requirements.txt for pip compatibility
uv pip freeze > requirements.txt

Others can then use:

pip install -r requirements.txt

Troubleshooting

Environment Not Activating

Problem: Activation script not found or permission errors.

Solution:

  1. Verify environment was created: Check that .venv directory exists
  2. Use full path to activation script:
# Windows
C:\path\to\project\.venv\Scripts\activate

# macOS/Linux
source /path/to/project/.venv/bin/activate
  1. On Windows, if you get execution policy errors:
Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser

Path Conflicts with Multiple Python Installations

Problem: Wrong Python version being used.

Solution:

  1. Specify Python version explicitly when creating environment:
uv venv --python 3.12
  1. Check which Python is being used:
# In activated environment
which python  # bash, NuShell
where python  # Windows PowerShell

Version Conflicts

Problem: Incompatible package versions.

Solution:

  1. Use uv’s dependency resolver:
uv pip install package1 package2 --resolution highest
  1. Check conflict details:
uv pip install --dry-run package1 package2
  1. Pin specific versions in pyproject.toml:
dependencies = [
    "package1>=1.0,<2.0",
    "package2==3.5.0",
]

Integration with IDEs

VS Code

  1. Select Python Interpreter:
    • Press Ctrl+Shift+P (Windows/Linux) or Cmd+Shift+P (macOS)
    • Type “Python: Select Interpreter”
    • Choose the .venv/bin/python (or .venv\Scripts\python.exe on Windows)
  2. Automatic Activation:
    • VS Code automatically activates the environment in integrated terminal
    • Create .vscode/settings.json:
{
    "python.defaultInterpreterPath": "${workspaceFolder}/.venv/bin/python"
}
  1. Recommended Extensions:
    • Python extension (Microsoft)
    • Pylance (Microsoft)
    • Jupyter (Microsoft)

JupyterLab

  1. Install Jupyter in Environment:
uv add jupyterlab ipykernel
  1. Register Environment as Kernel:
# Activate environment first
python -m ipykernel install --user --name=myproject --display-name="Python (myproject)"
  1. Launch JupyterLab:
uv run jupyter lab
  1. Select Kernel: In JupyterLab, choose “Python (myproject)” from the kernel menu.

Best Practices

Project Organization

Keep a clean project structure:

my-project/
├── .venv/                 # Virtual environment (don't commit)
├── data/                  # Data files (don't commit)
├── notebooks/             # Jupyter notebooks
├── src/                   # Source code
│   └── my_project/
├── tests/                 # Test files
├── .gitignore            # Ignore .venv, data/, etc.
├── pyproject.toml        # Project configuration
├── uv.lock              # Lockfile (commit this)
└── README.md            # Project documentation

Environment Naming

Use consistent naming:

  • .venv for standard virtual environments (recommended, works with most IDEs)
  • projectname-env for named environments
  • Avoid spaces in environment names

Dependency Management

  • Pin major versions: pandas>=2.0,<3.0 for stability
  • Use lockfiles: Commit uv.lock for reproducibility
  • Separate dev dependencies: Keep development tools separate from runtime dependencies
  • Document unusual dependencies: Add comments in pyproject.toml explaining non-obvious packages

Regular Maintenance

  • Update regularly: Run uv lock --upgrade monthly to get security patches
  • Test after updates: Run tests after upgrading dependencies
  • Review dependencies: Periodically audit and remove unused packages

Learning Resources

For general Python setup and data science workflows, see:

Back to top