Pixi: Multi-Language Package and Workflow Manager
Pixi is a cross-platform package manager and workflow tool that manages both conda-forge packages and PyPI packages from a single project manifest. It replaces conda’s global environment model with project-local environments and automatic lockfiles.
Note
Pixi targets the same package ecosystem as conda but with a different workflow model. If you don’t need conda-forge packages, uv is a simpler choice. See When should I choose pixi over uv? for a detailed comparison.
When to use pixi
Use pixi when your project depends on native libraries that conda-forge packages more reliably than PyPI: CUDA toolkits, GDAL, HDF5, OpenCV, MKL, NetCDF. Some of these have PyPI packages, but conda-forge bundles the underlying C/C++/Fortran libraries so you don’t need to install them separately. Pixi also works well for mixed-language projects (Python + R, Python + C++) and for teams that want reproducible cross-platform lockfiles covering both conda and PyPI dependencies.
For pure Python projects, uv provides a simpler workflow.
Installation
curl -fsSL https://pixi.sh/install.sh | bashThis installs the pixi binary to ~/.pixi/bin (macOS/Linux) or %UserProfile%\.pixi\bin (Windows). See the official installation guide for other methods.
Project setup
Initialize a new project with pixi init:
pixi init my-project
cd my-projectThis creates a pixi.toml manifest:
[workspace]
authors = ["Your Name <you@example.com>"]
channels = ["conda-forge"]
name = "my-project"
platforms = ["osx-arm64"] # auto-detected from your system
version = "0.1.0"
[dependencies]
[tasks]To use pyproject.toml instead (useful if you’re building a Python package):
pixi init --format pyproject my-projectWith pyproject.toml, pixi configuration lives under [tool.pixi.*] sections (e.g. [tool.pixi.workspace], [tool.pixi.dependencies]), while standard [project] metadata remains portable to other Python tools.
Managing dependencies
Conda packages
pixi add python numpy pandasPyPI packages
pixi add --pypi requestsPixi resolves conda dependencies first, then resolves PyPI packages against what conda already installed. It uses uv internally for PyPI resolution.
Installing the environment
pixi installThis creates a .pixi/ directory containing the project environment. The directory is local to the project and should be added to .gitignore (pixi does this automatically on pixi init).
Running commands
# Run a command in the project environment
pixi run python main.py
# Start an interactive shell
pixi shellRunning self-contained scripts
Pixi runs PEP 723 scripts directly, without a project directory or pixi.toml:
# /// script
# requires-python = ">=3.11"
# dependencies = ["rich>=13.9.2"]
# ///
import rich
rich.print("Hi from [bold magenta]hello.py[/bold magenta]!")pixi run --script hello.pyPixi reads the metadata block, creates an isolated environment with the listed packages, and runs the script. pixi init --script writes an empty block into a script that has none (it refuses a script that already carries one), and pixi add --script fills the block in:
pixi init --script report.py
pixi add --script report.py --pypi richMixing conda dependencies
Pixi extends the standard PEP 723 block with a [tool.pixi] section for conda packages, something uv and other PEP 723 runners cannot do. Omit --pypi and pixi add treats the package as a conda dependency:
pixi init --script earthquakes.py --channel conda-forge
pixi add --script earthquakes.py gdal
pixi add --script earthquakes.py --pypi httpxThose commands leave the script’s own code alone and write the metadata above it:
# /// script
# requires-python = ">=3.11"
# dependencies = ["httpx"]
#
# [tool.pixi.workspace]
# channels = ["conda-forge"]
#
# [tool.pixi.dependencies]
# gdal = "*"
# ///Another PEP 723 runner reads dependencies and ignores tool.pixi, so it installs httpx but not GDAL.
Running remote scripts and locking versions
pixi run --script accepts URLs, GitHub Gist URLs, or stdin (-):
pixi run --script https://example.com/fetch.py
pixi run --script - < fetch.pyRemote and stdin scripts must already carry a metadata block; only local paths can be edited, inspected, or locked.
To lock a script’s dependencies for reproducibility:
pixi lock --script hello.pyThis writes a hello.py.pixi.lock sidecar next to the script.
Tasks
Pixi includes a built-in task runner. Tasks are defined in pixi.toml and run within the project environment.
# Add tasks
pixi task add test "pytest -s"
pixi task add lint "ruff check ."
# Run a task
pixi run testTasks can also be defined directly in pixi.toml with dependencies on other tasks:
[tasks]
lint = "ruff check ."
test = { cmd = "pytest -s", depends-on = ["lint"] }Multi-environment support
Pixi can define multiple environments from composable “features.” Each feature is a named set of dependencies; environments combine one or more features. Named environments include the default feature’s dependencies unless you set no-default-feature = true.
[dependencies]
python = ">=3.12"
numpy = ">=2.0"
[feature.test.dependencies]
pytest = ">=8"
[feature.docs.dependencies]
sphinx = ">=7"
[environments]
test = ["test"]
docs = ["docs"]Run commands in a specific environment:
pixi run --environment test pytest
pixi run --environment docs sphinx-build docs buildCross-platform lockfiles
Pixi resolves dependencies for all target platforms in a single pixi.lock file. Add platforms with:
pixi workspace platform add linux-64 win-64The lockfile captures the full dependency graph for every platform and environment combination. Each platform is solved separately, so exact builds may differ across OSes, but every collaborator gets a reproducible install for their platform.
Pixi 0.68.0 (May 2026) upgraded the lockfile format to version 7. The upgrade is automatic on the next pixi lock or pixi update, but older pixi builds cannot read v7 lockfiles. Coordinate the upgrade across collaborators and CI before committing a regenerated pixi.lock. Version 7 also records build and host environments (making source builds reproducible across machines), eliminates churn from comment-only manifest edits, and keeps relative paths relative for Docker and cross-machine portability.
Tool management
Like pipx or uvx, pixi can install CLI tools globally or run them in temporary environments:
# Install a tool globally
pixi global install ruff
# Run a tool without installing it
pixi exec black --check .
# List globally installed tools
pixi global listBuilding packages from source (preview)
Pixi Build lets pixi build packages from source instead of only consuming prebuilt conda packages. The system uses language-specific build backends inspired by Python’s PEP 517 build backend protocol: pixi-build-python for Python projects (using hatchling and uv internally) and pixi-build-rust for Rust projects.
Enable the feature with a preview flag in pixi.toml:
[workspace]
preview = ["pixi-build"]Configure a build backend in the package manifest:
[package.build.backend]
name = "pixi-build-python"
[host-dependencies]
hatchling = "*"
[run-dependencies]
python = ">=3.12"Build dependencies stay isolated from the runtime environment. Pixi rebuilds packages in dependency order with caching, so a monorepo with path dependencies (fibtable = { path = "." }) rebuilds only what changed.
SciPy, Xarray, Dask, and CPython have adopted pixi-build in early preview. See the pixi-build documentation for the full configuration reference.
Other useful commands
# Search for a package on configured channels
pixi search opencv
# Show the dependency tree
pixi tree
# Show environment and system info
pixi info
# Update dependencies to latest compatible versions
pixi updateSupply chain security
Pixi 0.67.0 added exclude-newer, which delays adoption of newly released packages by a configurable period. This allows vulnerabilities to surface in the ecosystem before they reach a project’s resolved dependencies.
Set a workspace-wide cooldown in pixi.toml:
[workspace]
exclude-newer = "7d"Per-channel or per-package overrides are supported for packages under internal control:
[workspace]
channels = [
"conda-forge",
{ channel = "https://prefix.dev/my-channel", exclude-newer = "0d" },
]
exclude-newer = "14d"
[exclude-newer]
my-internal-package = "0d"The value accepts a duration ("7d", "30d") or an ISO date ("2026-01-01"). The setting applies to both conda and PyPI packages.
Learn more
- Create your first Python project with pixi (Tutorial)
- Set up a GPU data science project with pixi (Tutorial)
- How to migrate from conda to pixi (How To)
- When should I choose pixi over uv? (Explanation)
- uv vs pixi vs conda for scientific Python (Explanation)
- Pixi documentation
- Pixi GitHub repository
- Switching from conda to pixi