Skip to main content
Learn the three types of package dependencies and their specific roles in the build process.

Overview

Package dependencies in Pixi are more granular than workspace dependencies. While workspace dependencies are simply packages available in environments, package dependencies distinguish between when and where they’re needed:
[package.build-dependencies]
cxx-compiler = "*"  # Build machine, compile time

[package.host-dependencies]
catch = "*"         # Target machine, link time

[package.run-dependencies]
git = "*"           # Target machine, runtime
Think of it this way:
  • Build dependencies run on your machine during compilation
  • Host dependencies are compiled into your package
  • Run dependencies are needed when using your package

Build Dependencies

Build dependencies are tools needed to build the package, installed for the architecture of the build machine.

When to Use Build Dependencies

Use for tools that:
  • Run during compilation but aren’t compiled into the package
  • Generate code or resources
  • Are specific to your development machine

Common Examples

[package.build-dependencies]
cxx-compiler = "*"
c-compiler = "*"
fortran-compiler = "*"
Important for pixi-build-cmake users:The pixi-build-cmake backend automatically provides cmake, ninja, and C++ compilers. You don’t need to specify them:
# This is automatic with pixi-build-cmake
# [package.build-dependencies]
# cmake = "*"  # Not needed!
# ninja = "*"  # Not needed!
# cxx-compiler = "*"  # Not needed!

Cross-Compilation Example

Build dependencies enable cross-compilation:
[workspace]
platforms = ["linux-aarch64"]  # Target: Linux ARM

[package.build-dependencies]
cmake = "*"  # Runs on your x86_64 MacBook

[package.host-dependencies]
sdl2 = "*"   # ARM64 libraries for the target
Build vs Host Platform:
  • Build platform: Your machine (e.g., osx-arm64)
  • Host/target platform: Where the code runs (e.g., linux-aarch64)
The terminology comes from cross-compilation:
MachineDefinitionExample
BuildWhere compilation happensYour MacBook (osx-arm64)
HostWhere the code runsLinux server (linux-64)
TargetFor compilers: what they generate code forARM device (linux-aarch64)
For most builds, build = host = target.

Host Dependencies

Host dependencies are needed during build/link time and are specific to the target platform.

When to Use Host Dependencies

Use for:
  • Libraries you link against
  • Headers you include
  • Base interpreters (Python, R, Node.js)
  • Build backends for interpreted languages

Common Examples

[package.host-dependencies]
sdl2 = ">=2.26.5,<3.0"
boost = ">=1.70"
openssl = "*"
rapid
= "*"
xtensor = "*"

Python Build Backends

Python build tools must go in host-dependencies due to technical limitations:
[package.host-dependencies]
hatchling = "*"  # PEP 517 backend
uv = "*"          # Package installer
pip = "*"         # Alternative installer
Technical Limitation:Tools like hatchling, pip, and uv must be host dependencies (not build dependencies) to ensure they use the correct Python prefix during the build process. We’re working to improve this.

Native Code Libraries

When building C++ or other native code:
[package.host-dependencies]
sdl2 = "*"       # Will be linked into your binary
zlib = "*"       # Will be linked into your binary
libpng = "*"     # Will be linked into your binary

Cross-Compilation Scenario

Compiling on Linux x86_64 for Linux ARM:
Build Machine: linux-64 (your PC)
Target Machine: linux-aarch64
ComponentTypeBuildHostTarget
GCCCompilerx86_64x86_64aarch64
CMakeBuild toolx86_64x86_64N/A
SDL2LibraryN/Aaarch64N/A
Your AppApplicationx86_64aarch64N/A
[package.build-dependencies]
cmake = "*"  # x86_64 version

[package.host-dependencies]
sdl2 = "*"   # aarch64 version (target platform)

Run-Exports

Many conda packages define run-exports, which automatically add run dependencies:
[package.host-dependencies]
zlib = "*"  # Automatically added to run-dependencies via run-exports!
Most conda-forge packages have run-exports defined. When you add them to host-dependencies, they’re automatically added to run-dependencies - no need to specify twice!

Run Dependencies

Run dependencies (also just called “dependencies”) are required when using the package.

When to Use Run Dependencies

Use for:
  • Libraries loaded at runtime
  • Executables called by your package
  • Resources needed during execution

Common Examples

[package.run-dependencies]
rich = ">=13.9"
requests = "*"
numpy = ">=1.20"

Run Dependencies in Workspaces

Run dependencies are similar to workspace dependencies:
# Workspace dependency
[dependencies]
rich = "*"

# Package run dependency
[package.run-dependencies]
rich = "*"
Both make the package available at runtime, but package run-dependencies are included when others depend on your package.

Path Dependencies

Depend on other packages in your workspace:
[package.run-dependencies]
cpp_math = { path = "packages/cpp_math" }
core_utils = { path = "../core_utils" }
See the workspace guide for multi-package examples.

Complete Example

Here’s a C++ package with all three dependency types:
pixi.toml
[workspace]
channels = ["https://prefix.dev/conda-forge"]
platforms = ["linux-64", "osx-64", "osx-arm64", "win-64"]
preview = ["pixi-build"]

[dependencies]
my_package = { path = "." }

[package]
name = "my_package"
version = "0.1.0"

[package.build.backend]
name = "pixi-build-cmake"
version = "0.3.*"

# Tools that run during build on your machine
[package.build-dependencies]
pkg-config = "*"     # Find library paths
autoreconf = "*"     # Generate configure scripts

# Libraries linked into the package
[package.host-dependencies]
sdl2 = ">=2.26.5,<3" # Graphics library
openssl = "*"        # Crypto (has run-exports)
boost = ">=1.70"     # C++ utilities

# Runtime requirements
[package.run-dependencies]
ffmpeg = "*"         # Video processing
git = "*"            # Version control access
# openssl added automatically via run-exports

Python Package Example

pixi.toml
[workspace]
channels = ["https://prefix.dev/conda-forge"]
platforms = ["linux-64", "osx-64", "osx-arm64", "win-64"]
preview = ["pixi-build"]

[dependencies]
my_py_package = { path = "." }

[package]
name = "my_py_package"
version = "0.1.0"

[package.build.backend]
name = "pixi-build-python"
version = "0.4.*"

# Build tools for Python
[package.host-dependencies]
python = ">=3.11"    # Base interpreter
hatchling = "*"      # PEP 517 backend
numpy = ">=1.20"     # Build-time headers

# Runtime dependencies
[package.run-dependencies]
rich = ">=13.9"      # CLI formatting
requests = "*"       # HTTP client
numpy = ">=1.20"     # Also needed at runtime
numpy appears in both host-dependencies (for headers during compilation of extensions) and run-dependencies (for runtime imports). This is common for packages with both C and Python components.

Decision Guide

Use this flowchart to determine dependency type:
Does it run during the build?

├── Yes: Is it compiled into the package?
│   │
│   ├── Yes: HOST DEPENDENCY
│   │    Examples: libraries, headers, Python
│   │
│   └── No: BUILD DEPENDENCY
│        Examples: CMake, compilers, code generators

└── No: Is it needed at runtime?

    └── Yes: RUN DEPENDENCY
         Examples: libraries, executables, Python packages

Quick Reference Table

AspectBuildHostRun
When usedCompile timeLink timeRuntime
PlatformBuild machineTarget machineTarget machine
Examplescmake, compilerslibraries, headersexecutables, libraries
Installed whereBuild environmentTarget packageUser environment
Cross-compileBuild platformHost platformHost platform

Common Patterns

[package.build-dependencies]
# Usually none (pixi-build-cmake provides tools)

[package.host-dependencies]
python = ">=3.11"
nanobind = "*"
boost = "*"

[package.run-dependencies]
# Many added via run-exports automatically
[package.host-dependencies]
python = ">=3.11"
hatchling = "*"

[package.run-dependencies]
requests = "*"
rich = "*"
click = "*"
[package.build-dependencies]
rust = ">=1.70"
cargo = "*"

[package.host-dependencies]
openssl = "*"

[package.run-dependencies]
# Usually minimal - statically linked
[package.build-dependencies]
pkg-config = "*"

[package.host-dependencies]
python = ">=3.11"
nanobind = "*"
sdl2 = "*"
openssl = "*"

[package.run-dependencies]
ffmpeg = "*"
# sdl2, openssl added via run-exports

Understanding Run-Exports

Run-exports automatically propagate dependencies:
# You write:
[package.host-dependencies]
zlib = "*"
openssl = "*"

# Conda automatically adds to run-dependencies:
# zlib = ">=1.2.13,<2.0"
# openssl = ">=3.0.0,<4.0"
View a package’s run-exports:
pixi info zlib
Run-exports prevent version mismatches between build and runtime. If you build against zlib 1.2.13, run-exports ensure users get a compatible version.

Best Practices

Add only what’s strictly needed:
# Good - minimal
[package.host-dependencies]
python = ">=3.11"
hatchling = "*"

[package.run-dependencies]
rich = "*"
Don’t duplicate host and run dependencies if run-exports exist:
# Good - let run-exports handle it
[package.host-dependencies]
zlib = "*"

# Bad - redundant
[package.host-dependencies]
zlib = "*"
[package.run-dependencies]
zlib = "*"  # Unnecessary!
Use version constraints appropriately:
[package.host-dependencies]
python = ">=3.11,<3.14"  # Specific range
nanobind = ">=2.4,<3"    # Major version

[package.run-dependencies]
rich = ">=13.9"           # Minimum version
Comment why dependencies exist:
[package.host-dependencies]
python = ">=3.11"  # Requires match-case syntax
nanobind = ">=2.4" # Need type stub support

[package.run-dependencies]
ffmpeg = "*"       # Video format conversion

Next Steps

Build Backends

How backends use different dependency types

Build Variants

How variants affect dependencies

C++ Packages

Dependency types in C++ builds

Python Packages

Dependency types in Python builds

Troubleshooting

Ensure it’s in host-dependencies:
[package.host-dependencies]
library-name = "*"
Add to build-dependencies:
[package.build-dependencies]
tool-name = "*"
Add to run-dependencies:
[package.run-dependencies]
missing-package = "*"
Verify dependency type:
  • Build deps use build platform
  • Host deps use target platform
# For cross-compilation
[package.build-dependencies]
cmake = "*"  # Your machine's arch

[package.host-dependencies]
sdl2 = "*"   # Target machine's arch