Build
Screens from React
Design screens in React and TSX, and let the Screen Compiler turn them into native Rust for NoWayOS at build time: the supported subset, the commands, and why it refuses rather than guesses.
NoWayOS has no browser, and never will: that is the point. But designers and front-end developers can keep their tools. The Screen Compiler converts React screens, written in TSX to a declared subset, into Rust for NoWayOS's UI runtime. It runs at build time, on your machine or in CI, and never ships to the device.
From this
export function WelcomeScreen({ onStart, onHelp }: WelcomeProps) {
return (
<Screen>
<Column gap={SPACE_SM} padding={SPACE_LG}>
<Text id="title">Welcome</Text>
<Text>Touch Start to begin.</Text>
<Spacer />
<Button id="start" onPress={onStart}>Start</Button>
<Button onPress={onHelp}>Help & accessibility</Button>
</Column>
</Screen>
);
}
To this
pub fn build<B: ui::UiBuilder>(b: &mut B) -> Result<Nodes<B::Node>, B::Error> {
let n1 = b.text("Welcome")?; // welcome.tsx:17:9 <Text>
let n2 = b.text("Touch Start to begin.")?; // welcome.tsx:18:9 <Text>
let n4 = b.spacer(None)?; // welcome.tsx:20:9 <Spacer>
let n5 = b.button("Start", actions::START)?; // welcome.tsx:21:9 <Button>
let n6 = b.button("Help & accessibility", actions::HELP)?; // welcome.tsx:24:9 <Button>
let n0 = b.column(ui::Layout::new().gap(super::tokens::SPACE_SM).padding(super::tokens::SPACE_LG), &[n1, n2, n4, n5, n6])?; // welcome.tsx:16:7 <Column>
Ok(Nodes { root: n0, title: n1, start: n5 })
}
Each node points back to the line and column of the TSX it came from. The converted screen is then drawn by NoWayOS's renderer and must match its approved image, pixel for pixel. (Shortened from the repository's fixtures/welcome.tsx and its generated Rust.)
What it converts
Screens built from the Screen Compiler's kit: Screen, Column, Row, Text, Button, TextInput, Checkbox, RadioGroup, Spacer, Card, Notice, HeaderBar, ProgressBar and Icon. Also design tokens as constants, callback props that become actions, text the application sets at run time, and parts the application shows or hides ({cond && <X/>}).
Exact or nothing. Anything outside the subset is refused, with the file, line and column, never approximated. The same screen gives byte-identical Rust on any machine. The generated code has no unsafe, no unwrap and no panic.
Try it
The Screen Compiler's dev container and its contract check come from NoWayOS, so clone the two side by side:
mkdir nowayos && cd nowayos
git clone https://github.com/NoWayOS/nowayos.git nowayos
git clone https://github.com/NoWayOS/screen-compiler.git screen-compiler
make -C nowayos container # the dev image, once
cd screen-compiler
make test # unit, property, snapshot and command-line tests
make run ARGS="check fixtures/welcome.tsx" # check one screen against the subset
make contract-check # build every screen against NoWayOS's UI, and draw it
Approved images
Every converted screen has an approved image. When a change to a screen, or to NoWayOS's layout or drawing, changes what it looks like, redraw the images with make bless-images in screen-compiler. A person looks at each one and approves it before it is committed. From the nowayos side, make screen-compiler-check shows which approved images a change would alter.
Use it on your own screens only
The Screen Compiler is a build tool, not a sandbox. Convert TSX you trust, as you would compile code you trust.
Licence
The Screen Compiler is MIT. The Rust it generates from your screens is yours, to license as you wish.