Skip to content

Migrate a conda project to pixi

This tutorial converts a conda project (defined by an environment.yml) into a pixi project. The result: project-local environments, an automatic lockfile, a built-in task runner, and access to the same conda-forge packages.

Prerequisites

Why migrate

Conda works, but pixi solves several friction points:

  • Project-local environments instead of globally named ones that collide across projects.
  • Automatic lockfile (pixi.lock) generated on every pixi add, with no separate export step.
  • Built-in task runner that replaces the shell scripts or Makefiles used alongside conda.
  • Faster resolution for complex dependency trees.
  • Same packages from conda-forge (and PyPI when needed).

See When Should I Choose pixi Over uv? for more context on when pixi is the right tool.

Start with a sample environment.yml

If you have your own environment.yml, use that. Otherwise, save this example to follow along:

environment.yml
name: analysis
channels:
  - conda-forge
dependencies:
  - python=3.12
  - pandas=2.2
  - matplotlib=3.9
  - scikit-learn=1.5
  - jupyter
  - pip:
    - seaborn

Import into pixi

$ pixi init --import environment.yml
✔ Created /path/to/analysis/pixi.toml

If you see Error: × pixi.toml already exists, the directory is already a pixi project. Move to a fresh directory or delete the existing pixi.toml. If you see failed to open file 'environment.yml', you ran the command from a directory that doesn’t contain the file you saved.

This reads the environment.yml and generates a pixi.toml with the same channels, dependencies, and any pip packages.

Notice that pixi init also drops a .gitignore (with .pixi/* already excluded) and a .gitattributes (so the upcoming pixi.lock renders sensibly in diffs) into the directory. You did not write either file; pixi did. The actual pixi.lock is not generated until the next step.

Review the generated pixi.toml

Open pixi.toml and check what pixi created:

pixi.toml
[workspace]
name = "analysis"
channels = ["conda-forge"]
platforms = ["osx-arm64"]

[dependencies]
python = "3.12.*"
pandas = "2.2.*"
matplotlib = "3.9.*"
scikit-learn = "1.5.*"
jupyter = "*"

[pypi-dependencies]
seaborn = "*"

A few things to note:

  • The channels list matches the original file.
  • Conda dependencies appear under [dependencies].
  • Packages from the pip: section in environment.yml appear under [pypi-dependencies]. Pixi handles installing these from PyPI automatically.
  • The platforms field reflects your current machine. Add other platforms if your team uses different operating systems (e.g., platforms = ["osx-arm64", "linux-64"]).

Verify the environment

Install and test that everything works:

$ pixi install
✔ The default environment has been installed.
$ pixi run python -c "import pandas; import sklearn; print('All imports OK')"
All imports OK

If you see Error: × could not find pixi.toml or pyproject.toml, you ran pixi install from outside the project. cd into the directory that contains pixi.toml and try again.

pixi install creates the project-local environment in .pixi/. The pixi run command executes within that environment.

Notice the new .pixi/ directory and the pixi.lock file at the project root. The directory holds the resolved environment (Python plus every requested package and its transitive dependencies); the lockfile pins exact versions and build strings so pixi install produces the same environment for every teammate.

Replace conda habits

The workflow mapping from conda to pixi:

Conda command Pixi equivalent Notes
conda activate analysis pixi shell Spawns a subshell with the environment active
conda install scipy pixi add scipy Adds to pixi.toml and updates the lockfile
pip install some-pkg pixi add --pypi some-pkg Tracked in [pypi-dependencies]
conda env export (automatic) pixi.lock is always up to date
conda env create -f ... pixi install Recreates from pixi.toml + pixi.lock
conda list pixi list Shows installed packages

Add tasks to replace shell scripts

If your conda project used a Makefile or shell scripts for common operations, move those into pixi.toml:

pixi.toml
[tasks]
analyze = "python analyze.py"
test = "pytest"
notebook = "jupyter lab"

Run them with pixi run analyze, pixi run test, etc. Tasks are version-controlled alongside the project and discoverable by any teammate.

Commit the project

Add these files to version control:

git add pixi.toml pixi.lock analyze.py test_analyze.py data/

Confirm .pixi/ is in .gitignore. pixi init --import already wrote this entry, so the file should look like:

.gitignore
# pixi environments
.pixi/*
!.pixi/config.toml

If you started this project some other way (or deleted the auto-generated .gitignore), add the lines above before committing.

The pixi.lock file is the equivalent of a fully-pinned environment-lock.yml, but it’s generated automatically and stays in sync with pixi.toml. Teammates run pixi install to get the exact same environment.

Clean up the conda environment

Once you’ve verified the pixi project works, remove the old conda environment:

conda deactivate
conda env remove -n analysis

Keep the environment.yml for a transition period if other team members haven’t switched yet.

Next steps

Last updated on

Please submit corrections and feedback...