Build Your First Runtime#
This tutorial builds a local conda runtime named demo from either a
conda-workspaces project or a Pixi project.
You will create a small project, lock it, build a runtime binary, bootstrap that runtime into a temporary install path, and then remove it again.
Before You Start#
You need:
conda-shipeither conda-workspaces or Pixi
network access for solving and for the first bootstrap
Install the tools in an environment where you want to run the builder:
conda create -n cs-demo -c conda-forge python pip conda-workspaces
conda activate cs-demo
python -m pip install conda-ship
Check that both commands are available:
conda ship --help
conda workspace --help
conda create -n cs-demo -c conda-forge python pip pixi
conda activate cs-demo
python -m pip install conda-ship
Check that both commands are available:
cs --version
pixi --version
Create A Project#
Create an empty project directory:
mkdir demo-runtime
cd demo-runtime
Then choose the manifest tool you want to use. The two paths produce the same
runtime intent: a ship environment containing conda itself, the rattler solver
plugin, and conda-spawn for demo shell.
Create a conda.toml:
conda workspace init --format conda --name demo-runtime
Add the runtime packages to a ship feature. conda workspace add creates the
matching ship environment in the manifest:
conda workspace add --feature ship --no-lockfile-update \
"python>=3.12" \
"conda>=25.1" \
conda-rattler-solver \
"conda-spawn>=0.1.0"
Add conda-ship’s build policy:
cat >> conda.toml <<'TOML'
[tool.conda-ship]
runtime = "demo"
runtime-version = "0.1.0"
delegate = "conda"
layout = "online"
source-environment = "ship"
exclude = ["conda-libmamba-solver"]
TOML
Create a pixi.toml:
pixi init --channel conda-forge
Add the ship feature, ship environment, and conda-ship build policy:
cat >> pixi.toml <<'TOML'
[feature.ship.dependencies]
[environments]
ship = { features = ["ship"], no-default-feature = true }
[tool.conda-ship]
runtime = "demo"
runtime-version = "0.1.0"
delegate = "conda"
layout = "online"
source-environment = "ship"
exclude = ["conda-libmamba-solver"]
TOML
Use Pixi’s native add command to put packages in the ship feature:
pixi add --feature ship --no-install \
"python>=3.12" \
"conda>=25.1" \
conda-rattler-solver \
"conda-spawn>=0.1.0"
Lock The Project#
Solve the source lockfile with the tool that owns the manifest:
conda workspace lock
This writes conda.lock.
pixi lock
This writes pixi.lock. The earlier pixi add --no-install command may have
already refreshed it; running pixi lock here makes the tutorial state
explicit.
conda-ship consumes the matching lockfile; it does not solve directly from loose package names during normal builds. The builder will derive its own runtime lock from this source lockfile.
Inspect The Package Set#
Run a preflight check before building. This derives the runtime package set, applies exclusions, and prints the selected packages without writing files:
conda ship inspect
cs inspect
The output lists the manifest and lockfile conda-ship selected, each locked platform, and the package set for your current platform.
Build The Runtime#
Build an online runtime named demo:
conda ship build
cs build
The generated runtime is written to dist/demo on Unix and dist/demo.exe on
Windows.
An online runtime contains the lockfile and runtime metadata. It downloads conda package archives when it bootstraps.
Smoke-Test The Runtime#
For this tutorial, bootstrap the generated runtime into a temporary local path to prove that the artifact works:
mkdir -p .tmp
./dist/demo --path "$PWD/.tmp/demo" bootstrap
This creates a conda installation managed by the demo runtime. This local
bootstrap is only a smoke test; a real downstream distribution should document
how its users install and update the runtime it publishes.
Note
The explicit --path keeps this tutorial install inside the project directory.
Published runtimes should document their normal install location and reserve
--path for local testing or advanced overrides.
Check it:
./dist/demo --path "$PWD/.tmp/demo" status
The status output shows the install path, configured channels, package metadata, installed package count, and delegate executable path.
Clean up the temporary install:
./dist/demo --path "$PWD/.tmp/demo" uninstall --yes
Optional: Build An Embedded Runtime#
The embedded layout puts compressed package archives inside the generated binary. This makes the build slower and the binary larger, but bootstrap no longer needs to download package archives.
conda ship build --layout embedded
cs build --layout embedded
Embedded runtimes use the z suffix, so this stages dist/demoz on Unix and
dist/demoz.exe on Windows.
Smoke-test it:
./dist/demoz --path "$PWD/.tmp/demoz" bootstrap
./dist/demoz --path "$PWD/.tmp/demoz" status
./dist/demoz --path "$PWD/.tmp/demoz" uninstall --yes
What You Learned#
You created a small workspace project, solved it, built an online runtime, and used that binary to install and manage its own conda prefix in a temporary smoke test.
For a real downstream distribution, choose a runtime name owned by that
distribution, keep its package choices in the source manifest, and publish the
staged files from dist/.