Introduction
What Carte is, what it is for, and where it sits between your app and your UI.
Carte is routing and scoped state for any Rust UI. You describe which screens may appear beneath which in a route table. Each frame, Carte derives the active path from your app's state, mounts the state each screen needs while it is on that path, and drops it when the screen leaves. It has no dependencies and draws nothing.
Carte was extracted from Masque, a Rust UI language, where it began life as Masque's router. It no longer depends on Masque, and Masque does not depend on it. See Status and roadmap.
Who it is for
Carte is for Rust programs with more than a handful of screens, prompts and panels, where "what is on screen right now?" has started to need a real answer: editors, tools, games, and desktop apps. It works with immediate-mode toolkits such as egui as well as retained ones, because it never touches a widget.
How it fits together
An application built on Carte has three layers:
| Layer | Owns |
|---|---|
| Carte | What may appear beneath what, which screens are active, what is true about them, and who is told when it changes |
| Your UI | How each screen looks, given the state it reads |
| A binding | The frame loop: calling Carte, drawing what it says is visible, and applying what the UI asked for |
Carte sits at the bottom and knows nothing about the layer above it. The binding is your code, usually a few dozen lines in your app's frame function. It is the only layer that knows about both.
Inside Carte there are two halves, and they are one framework rather than two:
- Routing. A static route table, a walk that derives the path every frame, Escape offered to the deepest screen first, occlusion, and guards that refuse entry with a sentence.
- State. A store of scopes, each a plain Rust struct with a schema, written by producers once per frame and read by your views. Screens ask for changes by pushing actions onto an outbox.
The two halves meet in two places. A screen's scope lives exactly as long as the screen is on the path. And a screen's guard is an ordinary Rust function over the store.
What it is not
Carte is deliberately narrow. Be clear about the limits before you adopt it:
- It is not URL routing. There are no path parameters, no query strings and no history stack. Route ids are
&'static strvalues known at startup. Navigation means changing your app's state; the walk reads that state and the path follows. - It does not draw. It tells you which ids are visible. Your UI decides what each one looks like.
- It does not own your data. Your model stays yours. The store holds facts the screens present, not the presentation's bulk data, and not your whole app.
- It is not finished. The derive macros that write schemas and intent vocabularies for you are not in the crate yet, so today you write those by hand. Some of the routing trait is scaffolding. The roadmap lists what is missing.
Where to go next
- Installation: add the crate.
- Quick start: a small notes app with a table, a screen, a scope and a frame loop.
- The frame: what to call each frame, and why the order is fixed.
- Design principles: the rules the crate holds itself to.