Pixi Projects¶
How to work with a project generated with package_manager: pixi, and how
to migrate an existing pixi.toml-based project onto the template's layout.
Where the pixi configuration lives¶
The template stores pixi configuration in pyproject.toml under
[tool.pixi.*] — no standalone pixi.toml is generated. pixi reads
[tool.pixi.*] from pyproject.toml natively, and keeping everything in
one file means the project metadata ([project]) stays identical across
the uv / pixi / poetry choices. If you prefer a standalone pixi.toml you
can move the sections over (see below), but the generated tooling
(pixi.lock, CI, tasks) works with the pyproject.toml layout as-is.
The generated file contains:
[tool.pixi.workspace]
channels = ["conda-forge"]
platforms = ["linux-64", "osx-arm64", "osx-64", "win-64"]
[tool.pixi.pypi-dependencies]
my_package = { path = ".", editable = true }
[tool.pixi.environments]
default = { solve-group = "default" }
dev = { features = ["dev"], solve-group = "default" }
Runtime dependencies go into the standard [project] dependencies list and
dev dependencies into the standard [dependency-groups] dev group — pixi
picks both up as PyPI dependencies of the matching feature. (data_science /
kaggle projects additionally get an experiment feature under
[tool.pixi.feature.experiment.pypi-dependencies].)
Dependency format: flat tables¶
pixi dependencies are declared as a flat table — one name = "version"
entry per package:
[tool.pixi.dependencies]
python = ">=3.11"
numpy = ">=2"
Writing one sub-table per package is invalid TOML here and fails with
cryptic errors such as invalid character in string:
# WRONG — do not do this
[tool.pixi.dependencies.numpy]
version = ">=2"
conda vs PyPI packages¶
| Table | Source | Use for |
|---|---|---|
[tool.pixi.dependencies] |
conda-forge | native/non-Python libraries (ffmpeg, gdal, cmake, ...), and python itself |
[tool.pixi.pypi-dependencies] |
PyPI (pip) | everything pip-installable, including your project (editable) |
[project] dependencies / [dependency-groups] |
PyPI (pip) | same as above, in the standard PEP 621/735 places pixi also reads |
PyTorch and friends: conda-forge's pytorch builds lag the CUDA
releases and can be unsatisfiable on some platforms
(only pytorch<=1.0.2 is available-style solver failures). The reliable
pattern is to keep heavy ML packages on the PyPI side and, when you need
CUDA wheels, add the PyPI index explicitly (this is what generated kaggle
projects do for uv):
[tool.pixi.pypi-dependencies]
torch = { version = ">=2.6", index = "https://download.pytorch.org/whl/cu126" }
Check https://prefix.dev/channels/conda-forge for what a conda package
actually provides before putting it in [tool.pixi.dependencies].
Migrating an existing pixi.toml project¶
- Copy
[tool.pixi.*]sections from yourpixi.tomlintopyproject.toml— the table names are identical. - Move pure-Python runtime deps from
[dependencies]into[project] dependencies, and dev deps from[tool.dev-dependencies]/ features into[dependency-groups](or keep them under the matching[tool.pixi.feature.<name>.pypi-dependencies]). - Tasks survive verbatim:
[tasks]and[tool.pixi.feature.dev.tasks]work inpyproject.tomlexactly as inpixi.toml. - Delete
pixi.toml(if both files exist pixi preferspixi.tomland ignores yourpyproject.tomlsections), then runpixi installto regeneratepixi.lock.
Everyday commands¶
pixi run -e dev shell # dev environment (ruff/pytest/... installed)
pixi run test # tasks defined by the chosen task runner
pixi run -e dev --locked test # what CI runs (fails if pixi.lock is stale)
pixi update # refresh pixi.lock
CI picks the right tool automatically: the generated workflows install
setup-pixi when a pixi.lock is present (and setup-uv / poetry
otherwise), so no workflow edits are needed when switching package
managers.