Dark
CUI
A web language based on CSS syntax that compiles to HTML + Wasm. No JavaScript.
HTML →
.button { background: "blue"; color: "white"; cursor: "pointer"; } page { button { text: "click me"; ?click { text: "clicked!"; } } }
<div style='display:inline-block; border-radius:4px;padding:8px 16px; border:none;font-size:0.9rem;' class='g'>click me</div> /* CSS (from .button class) */ .g { color:white; cursor:pointer; background:blue; } /* Wasm: click updates textContent */
Output:
click me
What is CUI?
CUI is a compiled language where structure, style, and behavior live in one CSS-like syntax. Classes define how things look. Instances create them. Listeners handle events. Variables wire them together. The compiler figures out the rest -- what's static gets baked into HTML, what's dynamic gets compiled to WebAssembly.
Why CUI?
Zero JavaScript
CUI compiles to WebAssembly. No bundler, no transpiler, no node_modules. Event handlers and reactivity run as native Wasm.
Three-layer compilation
The compiler detects what's fully static (baked into HTML), what needs one-time setup (wired up at page load), and what's truly reactive. Static pages have zero runtime cost.
CSS semantics you already know
Classes cascade. Properties inherit. If you know CSS, you know the mental model. CUI extends it to structure and behavior.
Four building blocks
Instances create elements. Classes define reusable styling. Listeners handle events. Variables connect them with reactive state. No components, no hooks, no lifecycle methods.
Interactive Tutorial
Learn CUI step by step. See concepts, code, and live demos that build on each other.
Start Tutorial →
How it works
CUI is a Rust procedural macro. Your source is parsed, analyzed, and compiled at build time:
CUI source -> parse -> AST -> analyze -> semantics tree -> cascade classes into instances -> compile -> HTML + CSS + Wasm
The cascade phase resolves class inheritance and variable scoping, and assigns each piece of content to a compilation layer. Only reactive parts incur runtime cost.
Get started
github.com/thisminute/cascading-ui
Built with CUI.
Tutorial
← Home
Overview
1. Text
2. Structure
3. Classes
4. Events
5. Variables
6. All Together
CUI Interactive Tutorial
Learn CUI by building up concepts one at a time. Each lesson shows you: what a feature does, the CUI code that uses it, a live demo, and the compiled output.
Start with Lesson 1 →
Lesson 1: The Text Property
The simplest thing: putting words on the page
Every element can have a text property. It sets the text content of that element. The compiler detects that this is static and bakes it directly into the HTML file. No runtime cost.
HTML →
greeting { text: "Hello, CUI!"; }
<div>Hello, CUI!</div> /* No CSS needed — pure text content */ /* Wasm: none — static HTML only */
Output:
Hello, CUI!
Next: Elements & Structure →
Lesson 2: Elements & Structure
Building hierarchy with nesting and styling
Elements in CUI are just names followed by braces. Nesting creates parent-child relationships in the DOM. CSS properties go directly on the element — just like CSS selectors, but inline.
HTML →
card { border-left: "4px solid #5865f2"; padding: "16px"; border-radius: "4px"; card_title { text: "My Card"; font-weight: "700"; margin-bottom: "8px"; } card_body { text: "Content inside the card."; opacity: "0.7"; } }
<div style='border-left:4px solid #5865f2; padding:16px;border-radius:4px;'> <div style='font-weight:700; margin-bottom:8px;'>My Card</div> <div style='opacity:0.7;'> Content inside the card.</div> </div> /* All inline styles — no classes needed */ /* Wasm: none — static HTML only */
Output:
My Card
Content inside the card.
← Text
Classes & Cascading →
Lesson 3: Classes & Cascading
Define once, reuse everywhere
A class (name starting with .) defines properties that cascade into all same-named instances. Instance properties override class properties. Classes can appear before or after instances — the compiler hoists them.
HTML →
.tag { padding: "6px 12px"; border-radius: "4px"; color: "white"; font-size: "0.9rem"; } tag { text: "Default"; background: "#5865f2"; } tag { text: "Custom"; background: "#ff6b6b"; } tag { text: "Another"; background: "#ffa500"; }
<div style='background:#5865f2;' class='o'>Default</div> <div style='background:#ff6b6b;' class='o'>Custom</div> <div style='background:#ffa500;' class='o'>Another</div> /* CSS (from .tag class) */ .o { color:white; padding:6px 12px; border-radius:4px; font-size:0.9rem; } /* Instance backgrounds are inline */ /* Wasm: none — static HTML only */
Output:
Default
Custom
Another
← Structure
Events & Interactivity →
Lesson 4: Events & Interactivity
Making things respond to user actions
Listeners (?click, ?blur, ?focus, etc.) respond to browser events. Properties inside a listener cascade onto the parent element when the event fires. Everything compiles to WebAssembly.
HTML →
button { text: "Click me"; color: "white"; background: "#5865f2"; cursor: "pointer"; ?click { text: "Clicked!"; background: "#ff6b6b"; } }
<div style='color:white;font-weight:500; cursor:pointer;background:#5865f2; border-radius:6px;border:none; display:inline-block; padding:10px 20px;'> Click me</div> /* All instance properties — inline */ /* Wasm: click updates text, background */
Output:
Click me
← Classes
Variables →
Lesson 5: Variables
Reactive state that connects elements
Variables (let $name: value) hold state. When a listener assigns a new value, every element reading that variable updates automatically. This is how one element's event can change another element's appearance.
HTML →
let $color: "#888"; let $status: "Waiting..."; label { text: $status; color: $color; font-style: "italic"; } button { text: "Activate"; cursor: "pointer"; ?click { $status: "Active!"; $color: "#5865f2"; } }
<div style='font-style:italic;color:#888; font-size:1.1rem;margin-bottom:12px;'> Waiting...</div> <div style='font-weight:500; border-radius:6px;color:white; display:inline-block;background:#5865f2; padding:10px 20px;cursor:pointer; border:none;'>Activate</div> /* Wasm: click updates $status text */ /* and $color on the label element */
Output:
Waiting...
Activate
← Events
Putting It Together →
Lesson 6: Putting It All Together
Structure + classes + events + variables in one component
Now let's combine everything. This to-do list uses: nested elements for structure, a class for shared item styling, apply to toggle checkbox state, and a variable so checking a box changes a separate status element.
HTML →
let $status: "nothing checked"; .item { display: "flex"; align-items: "center"; padding: "12px"; border-left: "4px solid #5865f2"; margin-bottom: "8px"; } .unchecked { width: "20px"; height: "20px"; background: "#ddd"; border-radius: "3px"; cursor: "pointer"; margin-right: "12px"; ?click { $status: "making progress!"; apply: .checked; } } .checked { width: "20px"; height: "20px"; background: "#5865f2"; border-radius: "3px"; cursor: "pointer"; margin-right: "12px"; ?click { $status: "unchecked one"; apply: .unchecked; } } status { text: $status; } item { unchecked {} label { text: "Learn CUI"; } } item { unchecked {} label { text: "Build something"; } }
<div style='color:#888;margin-bottom:12px; font-style:italic;'>nothing checked</div> <div class='s'> <div class='t'></div> <div>Learn CUI</div> </div> <div class='s'> <div class='t'></div> <div>Build something</div> </div> /* CSS (from .item and .unchecked) */ .s { display:flex; align-items:center; padding:12px; margin-bottom:8px; border-left:4px solid #5865f2; } .t { background:#ddd; width:20px; height:20px; cursor:pointer; margin-right:12px; border-radius:3px; } /* Wasm: click toggles class (apply), updates $status text */
Output:
nothing checked
Learn CUI
Build something
← Variables
That's the core of CUI.
Four building blocks — instances, classes, listeners, and variables — plus properties. The compiler handles the rest: cascading, scoping, and splitting your code across HTML, CSS, and WebAssembly.
← Back to Home