Native modules
A screen's logic in Rust, C, C++, or Zig — no JNI, no header files to write by hand.
A screen's own logic
A sibling file next to +screen.wh is that screen's native logic. The
extension picks the language: +screen.rs, .c, .cc, .cpp, or .zig.
// src/routes/report/+screen.rs — plain Rust; `pub` is the export rule
pub struct Summary { pub total: f64, pub outliers: Vec<f64> }
pub fn analyse(json: &str) -> Result<Summary, String> { … } // src/routes/report/+screen.wh
import $native
val s = $derived(analyse(raw)) Types are declared in the native source and flow outward; the .wh file
imports and declares nothing. $native always resolves to the current
screen's sibling — it names neither the file nor the language, because the extension
already chose.
What crosses
Primitives, String, structs and enums built from those, Vec<T>, Option<T>, and Result<T, E> — as a value, not an exception. Anything else is a build
error naming the vocabulary. Every crossing function is suspend, since a
call across the boundary is never assumed to be fast.
An app-scoped module
Logic more than one screen needs lives under src/lib/ instead, named the
way any other $lib import is:
// src/lib/codec.rs
pub fn decode(bytes: &[u8]) -> Result<String, String> { … } import $native.codec
val text = decode(bytes) Declaring dependencies
[native]
abis = ["arm64-v8a", "x86_64"]
[native.rust.dependencies]
serde = "1"
[native.module.codec]
include = ["vendor/codec"]
link = ["z"]
standard = "c17"
flags = ["-O2"] Rust crates go in [native.rust.dependencies]. A C or C++ module states its
own include, link, standard, and flags under [native.module.<name>]. [native] abis is stated once
for the app, not per module.
$tool
Running whitehall init --app inside an existing program gives that program a
screen without discarding it. $tool is the bridge: $tool.run is
the program's main with its arguments, and $tool.output, $tool.errors, $tool.running read its state.
See Also
- Coroutines — every crossing function is
suspend - Configuration —
[native]inwhitehall.toml - Project Structure — where
src/lib/sits