Skip to content

How do uv and conda compare?

uv and conda both create isolated environments and install packages, but they draw from different worlds. uv installs Python packages from PyPI. conda installs cross-language binaries from conda channels and ships its own Python. That single difference, where the packages come from, drives every trade-off below.

Where your packages come from

uv pulls from PyPI: prebuilt wheels and source distributions. For the interpreter itself, uv downloads a prebuilt python-build-standalone binary, so uv python install 3.13 needs no compiler. Everything uv installs is a Python package.

conda pulls from conda channels: the community-maintained conda-forge channel or Anaconda’s default channel. A conda package is not limited to Python. One package can carry a C library, a Fortran runtime, a command-line binary, or an R module. conda ships and manages its own Python interpreter as just another conda package.

That difference decides what each tool can install. If a dependency exists as a wheel on PyPI, uv installs it. If it needs a system library that PyPI cannot ship, conda’s channels usually carry it.

Which is faster?

uv is the faster installer by a wide margin. On an Apple Silicon laptop, uv add pandas resolved and installed pandas plus its dependencies from a cold cache in about one second; a warm cache dropped a repeat install to tens of milliseconds. conda’s default solver takes tens of seconds to a few minutes on a large environment.

conda has closed part of the gap. Since conda 23.10, the libmamba solver is the default, replacing the slower pure-Python solver. It speeds up resolution but does not match uv, partly because conda resolves heavier cross-language artifacts than uv’s Python wheels.

How reproducible is each?

uv writes a uv.lock that pins every transitive dependency with hashes and covers Linux, macOS, and Windows from one file. Committing it makes uv sync rebuild the same environment on any machine.

conda’s environment.yml is a specification, not a lock. It records the packages you asked for, not the exact resolved graph, so two conda env create runs weeks apart can produce different versions. Reproducing an exact conda environment across machines needs a separate tool, conda-lock, which writes a conda-lock.yml file.

How the daily workflow differs

uv is project-local. It creates a .venv inside the project, and uv run executes commands against it without an activation step. Switching projects means switching directories. Nothing is installed globally, and the environment is disposable because uv sync rebuilds it from the lockfile.

conda is global by default. You create a named environment with conda create -n myenv, activate it with conda activate myenv, and that environment lives in a central directory shared across every project on the machine. The model is familiar to research teams, but it invites environment sprawl and the occasional wrong-environment install.

Handling CUDA, GDAL, and other compiled dependencies

This is conda’s strongest ground. conda resolves a native library, its command-line tools, and the matching Python binding together in one solver pass, which is why the CUDA toolkit, GDAL, HDF5, and MKL-linked builds have lived in the conda world for years.

uv installs compiled packages when they ship self-contained wheels. NumPy, SciPy, and rasterio bundle their native libraries into the wheel, and PyTorch installs through index routing. uv hits a wall when a package has no self-contained wheel and needs a system library whose version must match exactly, like the standalone osgeo.gdal bindings. For a package-by-package breakdown, see uv vs pixi vs conda for scientific Python.

What about licensing?

The conda tool is free, BSD-licensed open source, and conda-forge is free for all use including commercial. What triggers a bill is Anaconda’s default channel at repo.anaconda.com: any organization with more than 200 employees needs a paid license to use it, and running conda install against that channel counts even from a free Miniconda install. Using Miniforge with conda-forge as the default channel avoids the charge entirely. See Is conda actually free? for the full terms.

uv carries no comparable terms. PyPI and uv are free for any use.

Side-by-side comparison

Consideration uv conda
Package source PyPI (wheels, sdists) conda channels (conda-forge, Anaconda default)
Ships the Python interpreter Yes (python-build-standalone) Yes (as a conda package)
Native / non-Python libraries Only via self-contained wheels First-class
CUDA, GDAL, MKL Wheel-dependent First-class
Resolution speed Fastest Slower (libmamba is the default solver)
Lockfile Built in, cross-platform (uv.lock) Separate tool (conda-lock)
Config format pyproject.toml environment.yml
Licensing Free (PyPI) Tool free; Anaconda default channel commercial above 200 employees
Best fit Pure-Python and PyPI projects Cross-language, native-heavy scientific stacks

Which should you use?

uv is the better default for most Python projects. When your dependencies are on PyPI as wheels, uv installs them faster, produces a pyproject.toml any standards-compliant tool can read, and manages Python versions without a second tool. See How to install Python with uv to start there.

Reach for the conda ecosystem when you need cross-language binaries or native libraries PyPI cannot ship: the CUDA toolkit resolved against matching packages, the full GDAL stack with its command-line tools, or an MKL-linked numerical build.

If you are adopting conda today for that reason, evaluate pixi first. pixi installs the same conda-forge packages, adds project-local environments and a single lockfile spanning conda and PyPI dependencies, and carries no Anaconda licensing obligation. When should I choose pixi over uv? covers that decision in depth.

Learn More

Last updated on