Development Environment Setup
Use the conda environment for normal Orbitron development. The other sections document narrower escape hatches:
- Conda Environment (see §2.3): the supported environment, what CI provisions, and what the rest of the Developer Guide assumes
- Docker + Dev Containers: isolated non-GUI builds, but no viewer-asset toolchain or nextest (see §2.1)
- System Packages: a reference for platform diagnosis and packaging, not the supported contributor environment
Commands outside §2.1 and §2.2 run inside conda, either after conda activate orbitron-dev or as conda run -n orbitron-dev <command>.
Before you export a web view: stage the WASM viewer assets
viewer/web-page (crate orbitron-web-page, which both ui/shell and automation/cli depend on) embeds three generated, gitignored files from extensions/python-bridge/python/orbitron/viewer_assets/. The Python bridge depends on it too, without its default embedded-viewer feature: Python’s export_html passes in the files its package ships to page_html_with_viewer, so the extension does not carry the viewer twice. Stage them with:
(cd viewer/wasm/ts && npm ci)
extensions/python-bridge/scripts/stage_viewer_assets.shA fresh clone builds without them. viewer/web-page/build.rs copies each asset into OUT_DIR and writes an empty placeholder for any that is absent, then prints a cargo:warning naming the staging script; viewer/web-page/src/lib.rs embeds from OUT_DIR rather than from the source tree. A placeholder can never be mistaken for a viewer, because assets_are_staged checks the WASM magic number and a plausible size before anything is embedded. So the only things that refuse on an unstaged clone are File > Export > Web View and orbitron web, at the point of use, with a message saying what to run. Until 2026-09-03 the assets were include_bytes!d straight from that directory and their absence failed the whole workspace build over one optional feature of one binary — which is the first thing a new clone hit.
Staging needs node/npm and trunk on PATH (both come with the conda environment). Re-run it after changing anything under viewer/wasm, or the notebook widget and the Web View export keep shipping the old wasm. CI does the equivalent in a dedicated build-viewer-assets job and hands the output to the other jobs through an exact-commit cross-OS cache, not a workflow artifact (see §13.2).
2.1 Docker + Dev Containers
Best for: Isolated builds of the non-GUI crates
Dockerfile.dev installs neither node nor trunk, so stage_viewer_assets.sh cannot run inside it. ui/shell still compiles — the build script substitutes empty placeholders and warns — but the resulting binary refuses File > Export > Web View. Stage the assets on the host first (or copy them in) if you need that export. If you are working on the desktop viewer, use the conda environment (§2.3) instead.
Why use Docker: - ✅ Same environment for everyone, regardless of OS - ✅ Isolated from host system (no dependency conflicts) - ✅ Easy onboarding - just docker-compose up or “Reopen in Container” in VS Code - ✅ No path configuration needed
(CI does not use the dev container: it builds Rust on native runners in the conda environment environment.yml describes.)
Prerequisites: - Docker and Docker Compose installed - For VS Code: Dev Containers extension
Quick Start:
Using Docker Compose:
# Build the development image (first time only, or after Dockerfile changes) docker-compose -f docker-compose.dev.yml build # Start interactive shell in container docker-compose -f docker-compose.dev.yml run --rm dev bash # Or run commands directly (no need to enter container) # Stage the viewer assets on the host first (see above) if you need the Web # View export; the build itself succeeds without them. docker-compose -f docker-compose.dev.yml run --rm dev cargo build --workspace --release docker-compose -f docker-compose.dev.yml run --rm dev cargo test --workspace --releaseUsing VS Code Dev Containers:
- Open the project in VS Code
- When prompted, click “Reopen in Container”
- Or use Command Palette: “Dev Containers: Reopen in Container”
- VS Code will automatically set up the environment with Rust extensions
Files: - Dockerfile.dev - Development container definition - docker-compose.dev.yml - Docker Compose configuration - .devcontainer/devcontainer.json - VS Code Dev Container configuration
What’s Included: - Rust 1.92.0 (pinned via rust-toolchain.toml; edition 2021) - HDF5 bundled by hdf5-metno and built through CMake - All build dependencies (cmake, pkg-config, etc.) - Cached build artifacts for faster rebuilds
Environment Variables: The container sets CARGO_INCREMENTAL=1 for faster rebuilds. No external HDF5 path is required on Linux or macOS.
Running Commands:
# Viewer assets must already be staged on the host (see above)
# Build the entire workspace
docker-compose -f docker-compose.dev.yml run --rm dev cargo build --workspace --release
# Test
docker-compose -f docker-compose.dev.yml run --rm dev cargo test --workspace --release
# Run CLI (note: use --bin to specify binary)
docker-compose -f docker-compose.dev.yml run --rm dev cargo run --release -p orbitron-cli --bin orbitron -- --help
# Interactive shell
docker-compose -f docker-compose.dev.yml run --rm dev bashBuild time depends heavily on CPU count, registry and npm cache state, and whether the WASM assets already exist. Docker volumes retain Cargo artifacts between runs. Use CARGO_BUILD_JOBS to leave headroom on a workstation rather than relying on an elapsed-time estimate from another machine.
Note: GUI viewer requires X11 forwarding or running on the host. For GUI development, consider using System Packages (see §2.2).
2.2 System Packages (Native Development)
Best for: Experienced developers, GUI development, fast iteration
Why use system packages: - ✅ Fast - no container overhead - ✅ Native tooling - direct access to system tools - ✅ GPU access - direct access to GPU for GUI development - ✅ Familiar - standard Rust development workflow
Prerequisites: - Rust toolchain (install via rustup) - System package manager (apt, brew, vcpkg, etc.) - node/npm and trunk, for the one-time viewer-asset staging (see above) - On Linux, libfontconfig1-dev. scripts/install-deps-linux.sh installs it. Without it the desktop dependency chain fails at the fontconfig probe, and the error is misleading: pkg-config --modversion fontconfig still succeeds while --libs --cflags does not. environment.yml carries fontconfig for the conda path, which is what CI uses.
Setup by Platform:
Linux (Debian/Ubuntu):
# Install dependencies, including libfontconfig1-dev, which the desktop
# stack needs.
./scripts/install-deps-linux.sh
# Stage the WASM viewer assets (one time, and after any viewer/wasm change)
(cd viewer/wasm/ts && npm ci)
extensions/python-bridge/scripts/stage_viewer_assets.sh
# Build
cargo build --workspace --releasemacOS:
# Install Homebrew if not already installed
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
# Install dependencies
./scripts/install-deps-macos.sh
# Stage the WASM viewer assets (one time, and after any viewer/wasm change)
(cd viewer/wasm/ts && npm ci)
extensions/python-bridge/scripts/stage_viewer_assets.sh
# Build
cargo build --workspace --releaseWindows:
# Prereqs: Visual Studio Build Tools + "Desktop development with C++"
# (MSVC v143 + Windows SDK). Use VS Installer -> Modify -> select workload.
# Conda setup (matches CI)
# 1. Install Miniconda/Anaconda and Git Bash.
# 2. From Git Bash, run: ./scripts/setup-conda-env.sh
# 3. In PowerShell, activate: conda activate orbitron-dev
# 4. Point pkg-config and PATH at conda's Library directory. Do NOT set HDF5_DIR
# or HDF5_ROOT: HDF5 is built from source and linked statically, and with
# HDF5_DIR set hdf5-metno-sys links that HDF5's DLL against a crate built for
# static symbols, and the build fails ("expected `&usize`, found `&i64`").
$env:PKG_CONFIG_PATH = "$env:CONDA_PREFIX\Library\lib\pkgconfig"
$env:PATH = "$env:CONDA_PREFIX\Library\bin;$env:PATH"
# Stage the WASM viewer assets. The script is bash — run it from Git Bash
# inside the activated env, or copy the three generated files from another
# machine's extensions/python-bridge/python/orbitron/viewer_assets/.
# (cd viewer/wasm/ts && npm ci)
# extensions/python-bridge/scripts/stage_viewer_assets.sh
# Build
cargo build --workspace --release
# Package like CI (optional). This is the short version. release.yml also
# stages the DirectX Shader Compiler (`./scripts/stage-windows-dxc.sh dist`)
# and scans each .exe for non-system DLL dependencies before archiving —
# see the "Prepare distribution (Windows)" job if you need the full chain.
# HDF5 is linked statically, so no conda DLL ships.
New-Item -ItemType Directory -Path dist -Force | Out-Null
Copy-Item target\release\orbitron-viewer.exe dist\
Copy-Item target\release\orbitron.exe dist\
New-Item -ItemType Directory -Path dist\packages -Force | Out-Null
Compress-Archive -Path dist\* -DestinationPath dist\packages\orbitron-windows.zip -Force
# Or use Docker (see §2.1)
# See scripts/install-deps-windows.sh for more system-package optionsTroubleshooting:
- Bundled HDF5 build fails: Confirm CMake is installed and inspect the
hdf5-metno-srcbuild output. On Windows, also confirm thatHDF5_DIRandHDF5_ROOTare unset.
2.3 Conda Environment (Recommended)
Best for: Everyone — this is the primary supported environment
Why use conda: - ✅ What CI’s Rust jobs run in, built from environment.yml, so a green local run means something - ✅ Isolated environment (similar to Docker) but with GPU and GUI access - ✅ Ships node and trunk, so the viewer assets can be staged - ✅ Good for scientific computing workflows and Python bridge development - ✅ Common in HPC environments - ✅ Environment variables automatically set via activation scripts
Setup:
Use the setup script. A bare conda env create omits the activation hook that sets PKG_CONFIG_PATH, which makes the desktop dependency chain fail later at the fontconfig probe.
# Creates environment from environment.yml and sets up activation scripts
./scripts/setup-conda-env.sh
# Activate the environment
conda activate orbitron-dev
# PKG_CONFIG_PATH is set by the activation script.
# Activation scripts properly expand ${CONDA_PREFIX} at activation time
# Stage the WASM viewer assets (one time, and after any viewer/wasm change)
(cd viewer/wasm/ts && npm ci)
extensions/python-bridge/scripts/stage_viewer_assets.sh
# Build
cargo build --workspace --releaseNote: - Activation scripts reliably expand ${CONDA_PREFIX} at activation time (unlike conda’s variables section which treats it as a literal) - Environment variables are automatically set when you activate the environment - no manual exports needed! - The environment.yml file defines packages; activation scripts handle environment variables - DYLD_LIBRARY_PATH is deliberately not set globally on macOS. Commands that need a non-system runtime library path set it only for their own child process; exporting conda’s library directory globally can crash ImageIO clients such as Chromium before their first window opens.
Customizing Environment Name:
ORBITRON_CONDA_ENV=myenv ./scripts/setup-conda-env.shFiles: - scripts/setup-conda-env.sh - Automated conda environment setup - environment.yml - Package specification consumed by the setup script
Troubleshooting:
- Conda not found: Install Miniconda or Anaconda first
- Environment already exists: The script will prompt to recreate it
- Path issues: Always use
$CONDA_PREFIX, never hardcoded paths