How to Migrate from conda to uv
This guide converts a conda project (defined by an environment.yml) into a uv project built on pyproject.toml and a uv.lock lockfile. The result: a project-local .venv, a cross-platform lockfile, and resolves and installs that finish in seconds instead of minutes.
Unlike the conda-to-pixi migration, there is no --import flag. uv reads from PyPI, not conda channels, so the migration is a re-declaration of your dependencies rather than a file conversion.
Confirm uv is the right target
uv fits a project whose dependencies all live on PyPI as wheels: NumPy, pandas, scikit-learn, matplotlib, SciPy, and most of the pure-Python scientific stack ship working wheels. For that stack, uv is the leaner choice and the fastest resolver available.
uv installs Python packages only. It cannot install the conda-only, non-Python dependencies conda-forge is built to provide:
- CUDA toolkits and GPU libraries resolved from conda-forge
- The standalone
gdalpackage and itsosgeo.gdalbindings, HDF5, or PROJ - Compilers and non-Python languages (R, Julia) sharing one environment
If your environment.yml pulls any of those from conda-forge, migrate to pixi instead, which keeps the project-local, lockfile-driven workflow while installing from conda-forge. See uv vs pixi vs conda for scientific Python and when should I choose pixi over uv? to confirm the call.
Translate environment.yml to pyproject.toml
Start from a typical scientific environment.yml:
name: analysis
channels:
- conda-forge
dependencies:
- python=3.12
- numpy
- pandas
- scikit-learn
- matplotlibCreate a uv project in the same directory, pinning the Python version from the python= line:
$ uv init --name analysis --python 3.12
Initialized project `analysis`
Add every package from the dependencies: list in one command. Packages under a pip: section in environment.yml go through the same uv add (they were already PyPI packages):
$ uv add numpy pandas scikit-learn matplotlib
Resolved 19 packages in 321ms
Installed 15 packages in 102ms
+ matplotlib==3.11.0
+ numpy==2.5.1
+ pandas==3.0.3
+ scikit-learn==1.9.0
+ scipy==1.18.0
uv writes the packages into [project.dependencies] and captures exact resolved versions in a lockfile (uv.lock):
[project]
name = "analysis"
requires-python = ">=3.12"
dependencies = [
"matplotlib>=3.11.0",
"numpy>=2.5.1",
"pandas>=3.0.3",
"scikit-learn>=1.9.0",
]Conda pins like numpy=1.26 become a version constraint if you pass it: uv add "numpy==1.26.*". Drop the pin to take the latest compatible release, as shown here.
Map conda commands to uv
The day-to-day workflow translation:
| Conda command | uv equivalent | Notes |
|---|---|---|
conda create -n analysis python=3.12 |
uv init --python 3.12 |
uv creates the .venv on the first uv add or uv sync |
conda activate analysis |
uv run <command> |
uv run python script.py uses the project venv with no activation step |
conda install scipy |
uv add scipy |
Adds to pyproject.toml and updates uv.lock |
pip install some-pkg |
uv add some-pkg |
Both come from PyPI; one command now |
conda env export |
uv lock |
uv.lock records the exact resolved versions |
conda env create -f environment.yml |
uv sync |
Recreates .venv from pyproject.toml + uv.lock |
conda list |
uv pip list |
Lists packages installed in the project venv |
To activate the environment the conda way instead of prefixing with uv run, source the venv directly: source .venv/bin/activate on macOS and Linux, or .venv\Scripts\activate on Windows.
Verify the environment
Recreate the environment from the lockfile and import the packages:
$ uv sync
$ uv run python -c "import numpy, pandas; print(numpy.__version__, pandas.__version__)"
2.5.1 3.0.3
If uv sync reports No pyproject.toml found in current directory or any parent directory, you ran it outside the project. cd into the directory that holds pyproject.toml and try again.
Remove the old conda environment
Once the uv project works, tear down the conda environment:
conda deactivate
conda env remove -n analysisCommit pyproject.toml and uv.lock so teammates reproduce the environment with uv sync; uv already added .venv/ to .gitignore. Keep the environment.yml around only while other team members finish switching.
Learn more
- How to Install Python (and Which Method to Choose)
- How do uv and conda compare?
- Which Python package manager should I use? for the full decision tree
- uv vs pixi vs conda for scientific Python for the package-source comparison
- Understanding the conda and Anaconda ecosystem for where conda-forge fits
- How to install Python with uv for managing interpreters without conda
- How to migrate from requirements.txt to pyproject.toml with uv for the pip-based path
- uv reference for the full command set