Python virtual environments explained: venv vs conda vs uv

Learn when to use Python's built‑in venv, Conda, or the ultra‑fast uv for clean, reproducible projects.

By Asahluma Tyika

Introduction – What’s a virtual environment and why you need one

When you write Python code you’re not just writing a single script; you’re pulling in libraries, tools, and sometimes different versions of the same library. Installing everything globally (i.e., with pip install straight into your system Python) quickly turns your machine into a tangled mess:

  • Project A needs NumPy 1.21, Project B needs NumPy 2.0.
  • A system upgrade breaks a script that relied on an older interpreter.
  • You can’t share a reproducible “this works on my machine” setup with teammates.

A virtual environment isolates a Python interpreter and its package directory so each project gets exactly what it asks for, and nothing else. This tutorial is aimed at beginners who have written a few scripts and now want a clean, repeatable workflow. We’ll compare three popular tools—venv, conda, and uv—show you how to set each up, and give you a hands‑on example you can run in five minutes.


Part 1 – Core concepts common to all tools

Concept What it means Why it matters
Interpreter The python executable that runs your code. Different projects may need Python 3.9 vs 3.11.
Package directory Where pip or conda stores installed wheels. Keeps dependencies isolated per project.
Activation A shell command that puts the virtual interpreter first on PATH. Allows you to run python and pip without typing full paths.
Lock file A machine‑readable list of exact package versions (requirements.txt, environment.yml, uv.lock). Guarantees reproducibility across machines.

All three tools provide these basics, but they differ in how they manage them, what extra features they bring, and how much they rely on external binaries.


Part 2 – venv – the built‑in, zero‑dependency option

When to choose venv

  • You already have a working Python installation (3.3+).
  • You want the simplest possible workflow, no extra installers.
  • Your project only needs pure‑Python packages or wheels available on PyPI.

Setup steps

# 1️⃣ Create a new directory for your project
mkdir my_venv_project && cd my_venv_project

# 2️⃣ Initialise a virtual environment named .venv
python -m venv .venv

# 3️⃣ Activate it (Linux/macOS)
source .venv/bin/activate

# 4️⃣ Activate it (Windows PowerShell)
# .venv\Scripts\Activate.ps1

# 5️⃣ Install a package with pip
pip install requests

# 6️⃣ Verify the interpreter path
which python   # Linux/macOS
# or
Get-Command python   # PowerShell

What venv does under the hood

  • Copies the base interpreter into the folder (.venv/bin/python).
  • Creates an empty site-packages directory for pip to fill.
  • Writes a small activate script that prepends the environment’s bin (or Scripts) folder to PATH.

Limitations

  • No built‑in package solver; you rely on pip’s simple dependency resolver.
  • No support for non‑Python binaries (e.g., conda’s compiled libraries).
  • No native lock‑file generation (you must create requirements.txt manually).

Part 3 – conda – the all‑in‑one data‑science manager

When to choose conda

  • Your project needs compiled libraries (e.g., numpy, pandas, scipy) that are tricky to build from source.
  • You want to manage multiple Python versions and non‑Python dependencies (e.g., libsqlite, ffmpeg).
  • You work in a data‑science or machine‑learning environment where the Anaconda/Miniconda distribution is already standard.

Install Miniconda (lightweight)

# Linux/macOS – download installer script
curl -fsSL https://repo.anaconda.com/miniconda/Miniconda3-latest-Linux-x86_64.sh -o miniconda.sh
bash miniconda.sh -b -p $HOME/miniconda

# Add to PATH for the current session
export PATH="$HOME/miniconda/bin:$PATH"

(Windows users can download the .exe installer from the same URL.)

Create and activate a conda environment

# 1️⃣ Create an environment named "myconda" with Python 3.11
conda create -n myconda python=3.11 -y

# 2️⃣ Activate it
conda activate myconda

# 3️⃣ Install a mix of Python and non‑Python packages
conda install numpy pandas -y      # pulls compiled binaries from conda‑forge
pip install fastapi                # pip works inside a conda env, too

# 4️⃣ Export a reproducible lock file
conda env export > environment.yml

What conda adds

Feature conda provides
Cross‑platform binaries Packages compiled for Windows, macOS, Linux in a single channel.
Channel system Official defaults and community‑run conda-forge let you pick the most up‑to‑date builds.
Environment export environment.yml captures Python version, channel URLs, and exact package builds.
Solver A SAT‑based dependency solver that can resolve complex version constraints quickly.

Drawbacks

  • The base installation (Miniconda/Anaconda) is ~400 MB, which may be overkill for tiny scripts.
  • Environments can become large because each one often includes its own copy of the Python interpreter and many compiled libs.

Part 4 – uv – the ultra‑fast, modern alternative

When to choose uv

  • You love speed: uv claims to be 10–100× faster than pip for installing wheels and creating environments.
  • Your workflow is pure‑Python (no need for heavy compiled libs).
  • You want a single binary that works on Windows, macOS, and Linux without a separate installer.

Install uv

# macOS / Linux – one‑liner
curl -LsSf https://astral.sh/uv/install.sh | sh

# Windows PowerShell
irm https://astral.sh/uv/install.ps1 | iex

The script drops uv into ~/.local/bin (Linux/macOS) or %USERPROFILE%\.uv\bin (Windows) and adds it to PATH.

Create a project with uv

# 1️⃣ Initialise a new project folder
mkdir my_uv_project && cd my_uv_project
uv init          # creates pyproject.toml and a basic src layout

# 2️⃣ Create a virtual environment (uv does it automatically on first install)
uv venv .venv    # optional: specify a location, otherwise .venv is default

# 3️⃣ Activate the env (same as venv)
source .venv/bin/activate   # Linux/macOS
# .venv\Scripts\Activate.ps1 # Windows PowerShell

# 4️⃣ Install packages – uv uses its own fast resolver
uv pip install httpx==0.27.0

# 5️⃣ Generate a lock file
uv lock

What makes uv special

Feature Description
Rust‑based resolver Compiled in Rust, giving sub‑second dependency solving even for large graphs.
Parallel wheel building Downloads and builds wheels concurrently, shaving minutes off large installs.
PEP 517/518 compliance Reads pyproject.toml for build requirements, so you can define build‑system metadata once.
Zero‑runtime dependencies A single executable; no Python interpreter required for the installer itself.

Caveats

  • Still relatively new (first stable release in 2023); some obscure packages may not yet have wheels that uv can handle.
  • Doesn’t manage non‑Python binaries; you’ll need conda or system packages for those.

Hands‑on example – A tiny Flask‑like web service

We’ll build a minimal HTTP server that fetches a JSON placeholder and prints the title. The code works with any of the three env managers; we’ll show the venv workflow, then note the equivalent conda/uv commands.

Project layout

my_demo/
├─ app.py
├─ requirements.txt   # for venv & pip
└─ environment.yml    # for conda (optional)

Step‑by‑step

# 1️⃣ Create the folder and move into it
mkdir my_demo && cd my_demo

# 2️⃣ Write the script (copy‑paste into app.py)
cat > app.py <<'PY'
import httpx

def main():
    resp = httpx.get("https://jsonplaceholder.typicode.com/todos/1")
    resp.raise_for_status()
    data = resp.json()
    print(f"Title: {data['title']}")

if __name__ == "__main__":
    main()
PY

Using venv

# Create and activate a venv
python -m venv .venv
source .venv/bin/activate   # Windows: .venv\Scripts\activate

# Pin the exact version we need
pip install "httpx==0.27.0"

# Freeze the environment (optional but helpful)
pip freeze > requirements.txt

# Run the script
python app.py

Using conda

conda create -n demo python=3.11 -y
conda activate demo
conda install -c conda-forge httpx -y   # pulls pre‑built binary
conda env export > environment.yml
python app.py

Using uv

uv venv .venv
source .venv/bin/activate
uv pip install "httpx==0.27.0"
uv lock               # creates uv.lock
python app.py

Expected output

Title: delectus aut autem

If you see that line, you’ve successfully isolated a Python interpreter, installed a third‑party library, and run code inside the environment—exactly what a virtual environment is meant to guarantee.


Common mistakes & troubleshooting

Symptom Likely cause Fix
command not found: python after activation Wrong activation script (e.g., used Windows activate on macOS) Run the correct script for your OS (source .venv/bin/activate on *nix, .venv\Scripts\Activate.ps1 on Windows PowerShell).
ImportError: No module named httpx Package installed in a different environment Ensure the environment is active (which python should point inside .venv). Re‑install with pip install httpx.
CondaValueError: prefix already exists Trying to create a conda env that already exists Either delete the old env (conda env remove -n demo) or reuse it (conda activate demo).
uv: error: could not find a version that satisfies the requirement … Package has no pre‑built wheel for your platform Fall back to pip inside the uv env (uv pip install package_name) or use conda for compiled libs.
Environment activation works, but python --version shows system Python Activation script modifies PATH incorrectly (e.g., missing export PATH=...) Re‑source the activation script or open a fresh terminal; avoid modifying PATH manually before activation.

Try it yourself

  1. Create a new folder called quiz_env.
  2. Initialise a venv (or conda/uv if you prefer).
  3. Install pandas==2.2.0 and matplotlib inside the env.
  4. Write a one‑line script that prints the first five rows of pandas.DataFrame({"a":[1,2,3]}).
  5. Run the script while the env is active and verify the output.

If you hit any of the errors above, apply the corresponding fix.


What’s next

  • Dependency lock files deep dive – how requirements.txt, environment.yml, and uv.lock differ and when to use each.
  • Cross‑platform CI pipelines – setting up GitHub Actions to test your project in venv, conda, and uv automatically.
  • Mixing conda and pip – best practices for installing pure‑Python wheels on top of a conda base.
  • Performance benchmarking – real‑world timing of pip, conda, and uv on a 100‑package data‑science stack.

Bookmark this guide for quick reference when you set up your next Python project.


Diagrams

Flowchart showing three parallel paths: venv → python -m venv → activate → pip install; conda → conda create → conda activate → conda install; uv → uv venv → source activate → uv pip install, converging on a “run script” box.

Flowchart showing three parallel paths: venv → python -m venv → activate → pip install; conda → conda create → conda activate → conda install; uv → uv venv → source activate → uv pip install, converging on a “run script” box.

Table comparing venv, conda, uv on dimensions (size, speed, binary support, lock file, OS), with colored bars indicating strengths.

Table comparing venv, conda, uv on dimensions (size, speed, binary support, lock file, OS), with colored bars indicating strengths.


This tutorial was drafted with AI assistance and verified with runnable examples. Found a mistake? Email the author — corrections are welcome.

Share: X (Twitter) Facebook LinkedIn