Native shells (SwiftUI + Jetpack Compose)
June 21, 2026 · View on GitHub
This directory is the in-repo counterpart to the old crepuscularity-native-ui worktree: Swift and Kotlin sample shells plus a shared IR fixture, alongside the Rust crate crepuscularity-native (../../crates/crepuscularity-native) that emits View IR (render_template_to_ir / to_json_pretty).
Rust on Android: the android-activity crate does let you ship native Rust as the process entrypoint (GameActivity / NativeActivity + winit/wgpu, etc.). It is not a UI framework—it replaces the Kotlin Activity shell while you draw or bridge UI yourself. A future path is: Rust (crepuscularity-native + parser) → IR → small Kotlin Compose or IR → GPU/text in Rust. The AOSP Rust modules doc is for platform / Soong builds, not typical Play Store Gradle apps—keep that separate from any sample here.
Coverage: IR and shells track a growing subset of Tailwind (style.rs) and widgets (button, img, scroll, slotRotate, …). This is not 100% parity with crepuscularity-gpui styler.rs—extend crates/crepuscularity-native/src/style.rs for missing classes.
Shared fixture
fixture.json matches the golden output for views/main.crepus:
div flex flex-col gap-4
span
"Hello {name}"
with name = Ada. Keep these copies in sync when you change the sample:
views/main.crepus(Crepus-authored source)fixture.json(repo root of this example)ios/Sources/NativeShell/fixture.json(SwiftPM resource)android/app/src/main/assets/fixture.json
iOS: Swift Package (this repo)
Use the checked-in ios/ tree as a local package (no XcodeGen required):
- Open
ios/Package.swiftin Xcode or addios/as a local Swift package dependency. - Import
NativeShelland useFixtureRootView(),ViewIrRootView(ir:), orViewNodeView(node:)from a hosting controller. - For a quick look, open
ViewIrTreeView.swiftand run an Xcode Preview onFixtureRootView.
Command-line build (macOS):
cd ios && swift build
SwiftPM writes ios/.build/ locally; it is listed in .gitignore and must not be committed.
iOS: CLI scaffold (crepus ios)
Alternatively, scaffold a fresh app (XcodeGen + app target) from anywhere you have the CLI installed:
wax install xcodegen
crepus ios new my-native-demo
cd my-native-demo
crepus ios generate
open *.xcodeproj
That lays out crepus.toml ([ios] holds scheme, xcodegen_spec, destination), XcodeGen project.yml, a local SwiftPM NativeShell package, and a minimal App target. crepus ios generate and crepus ios build walk up from the current directory (or any subfolder) until they find crepus.toml, so you do not need --dir / --scheme in normal use.
Optional overrides: crepus ios build --dir . --scheme Foo --destination 'platform=iOS Simulator,name=iPhone 15'.
CLI build (simulator), from inside the app tree:
crepus ios build
After changing templates, refresh scaffolded fixtures with crepus native sync views/main.crepus --dir . --var name=Ada --pretty, or write NativeShell/Sources/NativeShell/fixture.json directly using crepuscularity-native (see Rust ↔ JSON below).
Android
Open android in Android Studio (JDK 17+). Sync Gradle and run the app configuration.
From a terminal (with JAVA_HOME set):
cd android && ./gradlew :app:assembleDebug
Rust ↔ JSON
Generate IR from a template (from any crate that depends on crepuscularity-native):
use crepuscularity_core::TemplateContext;
use crepuscularity_native::{render_template_to_ir, to_json_pretty};
let mut ctx = TemplateContext::new();
ctx.set("name", "Ada");
let ir = render_template_to_ir(
"div flex flex-col gap-4\n span\n \"Hello {name}\"",
&ctx,
)?;
println!("{}", to_json_pretty(&ir)?);
JSON Schema for quicktype / other generators:
cargo run -p crepuscularity-native --features schema --bin export-view-ir-schema
CI does not build these shells yet; verify them locally when you touch the IR schema.
All components
views/all-components.crepus exercises the current native IR controls and can be regenerated with:
crepus native sync examples/native-shells/views/all-components.crepus --out examples/native-shells/all-components.fixture.json --pretty
crepus native codegen examples/native-shells/views/all-components.crepus --platform swiftui --out examples/native-shells/generated/swiftui --view-name AllComponentsView
crepus native codegen examples/native-shells/views/all-components.crepus --platform compose --out examples/native-shells/generated/compose --view-name AllComponentsView