Development Environment Setup

Use the conda environment for normal Orbitron development. The other sections document narrower escape hatches:

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.sh

A 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

The dev container cannot stage the viewer assets

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:

  1. 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 --release
  2. Using 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 bash

Build 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 --release

macOS:

# 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 --release

Windows:

# 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 options

Troubleshooting:

  • Bundled HDF5 build fails: Confirm CMake is installed and inspect the hdf5-metno-src build output. On Windows, also confirm that HDF5_DIR and HDF5_ROOT are unset.