Cargo Features in OpenHuman's Build Process: A Complete Guide to Conditional Compilation
OpenHuman uses Cargo feature flags to control three orthogonal aspects of the build: contributor defaults, product releases, and runtime domain gates.
The tinyhumansai/openhuman repository implements a sophisticated two-level feature model that separates compile-time code inclusion from runtime activation. This architecture enables fast local development while producing minimal, secure production binaries.
The Three Aspect Model of Cargo Features
OpenHuman's build system controls three distinct concerns through feature flags:
| Aspect | Purpose | Definition Location |
|---|---|---|
| Contributor feature set | Developer tools, linters, and test helpers enabled by default | Cargo.toml → [features] default = [...] |
| Product feature set | Crates shipped in the released desktop application | scripts/ci/product-features.txt |
| Domain-level runtime gates | Runtime switches for domain families (documents, web3, voice, channels, flows) | src/core/runtime/builder.rs |
Compile-Time Features vs. Runtime Domain Gates
The codebase deliberately decouples two systems for maximum flexibility.
Compile-time features in [features] are the only mechanism to remove code from the final binary. Use these to exclude heavy dependencies like libgit2-sys, ring, bzip2-sys, and zstd-sys from production builds.
Runtime domain gates via DomainSet keep code compiled but skip registration of controllers, stores, and agent tools. This reduces startup time and memory without recompilation.
A developer can compile all domains for full debug support while CI produces aggressively trimmed production binaries.
Feature Forwarding to the Tauri Shell
OpenHuman ships a Tauri desktop shell in app/src-tauri/. The shell depends on the core crate without default features:
# app/src-tauri/Cargo.toml
openhuman_core = { path = "../../", default-features = false, features = ["product"] }
The repository enforces consistency through scripts/ci/check-feature-forwarding.mjs. This script validates three invariants:
- Every feature in
scripts/ci/product-features.txtexists in core's[features] - Every default core feature is explicitly forwarded to the Tauri shell, unless listed in
INTENTIONALLY_NOT_FORWARDED(currently onlytui) - Forwarding sets are equal—no stray features enter the shell
Adding a New Feature
Follow this checklist when introducing features:
- Add the flag to root
Cargo.toml - Append to
scripts/ci/product-features.txtif shipping in product - Update
scripts/ci/check-feature-forwarding.mjsor add toINTENTIONALLY_NOT_FORWARDED
Key Feature Flags in OpenHuman
Several features demonstrate the system's design:
voice— Adds STT/TTS and podcast generation; pulls in heavycpalaudio stack; product-enabled but contributor-disabledweb3— Enables wallet and EVM/Bitcoin/Solana support; brings inethers-coreandcoins-bip39documents— Activates document generation tools; implicitly enablesmodulesfor PDF/DOCX codecstui— Terminal UI viaratatuiandcrossterm; intentionally not forwarded to desktop shell
All flags reside in root Cargo.toml with descriptive comments.
Build Scripts and Feature Usage
| Script | Feature Handling |
|---|---|
scripts/ci/full.yml |
cargo build --features "$(bash scripts/ci/product-features.sh)" |
scripts/ci/lite.yml |
Fast cargo check with default (developer) features |
scripts/kernel-floor.sh |
Computes minimal dependencies for kernel-only builds |
scripts/check-feature-forwarding.mjs |
Validates core-to-shell feature forwarding |
Computing the Kernel Floor
The scripts/kernel-floor.sh script determines the minimal dependency graph when compiling with --no-default-features --features flows. This prevents unintentional kernel footprint growth.
Building with Cargo Features
Full Product Binary
# Match CI production builds exactly
cargo build --release --features "$(bash scripts/ci/product-features.sh)"
Minimal Kernel-Only Binary
# Smallest possible runtime: flows domain only
cargo build --release --no-default-features --features "flows"
Runtime Domain Disabling
use openhuman_core::core::runtime::builder::{DomainSet, ServiceSet};
use openhuman_core::core::CoreBuilder;
// Exclude voice domain at runtime without recompilation
let core = CoreBuilder::new()
.domains(DomainSet::full().without_voice())
.services(ServiceSet::desktop())
.build()
.await?;
Method names follow the without_<domain>() pattern—see src/core/runtime/builder.rs for available helpers.
Adding a New Feature: Complete Example
Implementing an augmented_reality feature:
1. Declare in root Cargo.toml:
[features]
# existing flags…
augmented_reality = []
2. Add to product set if shipping:
echo "augmented_reality" >> scripts/ci/product-features.txt
3. The forwarding script reads product-features.txt automatically—no edit needed unless intentional exclusion.
4. Use conditional compilation:
#[cfg(feature = "augmented_reality")]
mod ar {
// AR-specific domain implementation
}
Why This Architecture Matters
- Binary size: Dropping native crates reduces
openhuman-corefrom ~300 MiB to ~67 MiB - Security surface: Native code features (
voice,web3) only present when explicitly enabled - CI speed: Lite lane compiles default features only; full lane validates production readiness
- Future-proofing: New domains gate behind compile-time flags first, then graduate to product set
Key Source Files
| File | Purpose |
|---|---|
Cargo.toml (root) |
Single source of truth for compile-time features |
scripts/ci/product-features.txt |
Shipped product feature list |
scripts/ci/check-feature-forwarding.mjs |
Core-to-shell consistency enforcement |
src/core/runtime/builder.rs |
Runtime DomainSet implementation |
scripts/kernel-floor.limits |
Kernel dependency budget |
app/src-tauri/Cargo.toml |
Tauri shell feature forwarding example |
Summary
- OpenHuman's Cargo features operate at three levels: contributor defaults, product releases, and runtime domain gates
- Compile-time features control binary content; runtime gates control activation without recompilation
- The Tauri shell disables default features and receives exact product set via forwarding scripts
- CI scripts maintain consistency:
product-features.txtdefines releases,check-feature-forwarding.mjsprevents drift - Kernel floor tracking ensures minimal dependencies for core-only builds
Frequently Asked Questions
What is the difference between default features and product features in OpenHuman?
Default features enable the full contributor experience with linters, test helpers, and optional native crates. Product features are the minimal set defined in scripts/ci/product-features.txt that ship in released desktop applications. The Tauri shell explicitly disables defaults with default-features = false and enables only the product set.
How do I exclude a domain without recompiling OpenHuman?
Use DomainSet::full().without_<domain>() when building the core. The code remains compiled—the domain simply isn't registered at startup. This pattern is implemented in src/core/runtime/builder.rs with methods like without_voice() for each available domain.
Why is the tui feature intentionally not forwarded to the desktop shell?
The tui feature pulls in ratatui and crossterm for terminal interfaces, which are unnecessary for the Tauri-based desktop application. Listing it in INTENTIONALLY_NOT_FORWARDED within scripts/ci/check-feature-forwarding.mjs prevents these crates from entering the desktop binary while keeping them available for headless or contributor builds.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →