facett — design (f0: the whole architecture)
Class:
design· Function axis: this isf0— how every facett function wires into one system. Each function has its own-design.md(linked below); this file is the spine that draws them together. Strict: only the shape we run — every why is inreasoning.md.
What facett is
facett is reusable data-viewing components for egui — each component is a facet of your data. Source-agnostic: hand one an Arrow RecordBatch, a graph, geo, or a DAG and it draws it, fast. It holds no connection or query logic (that stays in the data layer, e.g. knut). korp and nornir both build on it.
The two-part spine every component shares
facett is not a pile of widgets — it is one contract, twice. Every component sits on two stacked contracts, and everything else is a component family plugged onto that spine:
- The host-facing contract —
Facet. One trait:title/ui/state_json(+ a defaulted capability surface). A component is aBox<dyn Facet>; aFacetDeckcomposes many into one tabbed app and yields whole-app introspection for free. This is what makes "many components" compose. - The internal contract —
Elm. Inside a component, all observable state is one serializableModel, mutated only inupdate(&mut self, Msg), painted by a pureview(&self) -> Vec<Msg>. The macroimpl_facet_via_elm!writes theFacetimpl from theElmimpl. This is what makes any component testable without a window.
Between them they give the whole library its two defining properties: compose (Facet + FacetDeck) and assert headless (Elm + harness). 36 components impl Elm today.
The reuse graph (what uses what)
┌──────────────── egui 0.34 ────────────────┐
facett-core │ Facet · FacetDeck · FacetCaps · clipboard │ ← f: facet
(the kernel) │ Elm · impl_facet_via_elm! · harness │ ← f: elm, harness
│ Scene/Node/Edge · draw · Layout · clip │ ← f: render
│ Theme · NativeFeel · effects · chrome │ ← f: theming
└───────────────────┬───────────────────────┘
component families (each a crate, each an Elm+Facet):
grid ─ dataview ─ graph ─ map ─ map3d ─ pipeline ─ plot ─ docview
│
app (NavShell + Router + the demo deck that hosts them all)
Every family uses facett-core's four kernel functions (facet, elm, render, theming) and is driven by the fifth (harness). app uses every family. The kernel depends only on egui, serde, and its own modules — nothing downstream.
The functions
| function | what it is | design |
| facet | the host-facing component contract: Facet / FacetDeck / FacetCaps / clipboard |
facet-design.md |
| elm | the internal component loop: Model/Msg/pure-view/update + the bridge macro + harness seam |
elm-design.md |
| render | the CPU/GPU render kernel behind one draw() — Scene/Layout/clip, the wgpu fast path |
render-design.md |
| theming | the unified look: Theme presets, platform-adaptive NativeFeel, effects, chrome |
theming-design.md |
| harness | headless drive + snapshot + the test-matrix / robot seam | harness-design.md |
| grid | the flagship Arrow-backed virtualized data grid (+ the simpler table) | grid-design.md |
| dataview | browse + time-travel an Iceberg table; the warehouse deck | dataview-design.md |
| graph | node/edge visualizations: graph, the vello render engine, pan, 3D graph, system-map | graph-design.md |
| map | 2D geo: Web-Mercator map, scrollable geomap, GeoParquet ingest | map-design.md |
| map3d | 3D spatial: the 3D map (swappable RenderBackend) + the glTF model viewer |
map3d-design.md |
| pipeline | the engine-agnostic dataflow/DAG viewer (+ plan-DAG) | pipeline-design.md |
| plot | charting: line/bar plots, statistical plotters charts, progress | plot-design.md |
| docview | the documentation viewer — a Typst manual as one SVG per page | docview-design.md |
| app | the application framework: NavShell + Router + nav widgets, and the demo deck |
app-design.md |
The render kernel (one draw, CPU now, GPU behind it)
facett_core::draw is a CPU painter today; the wgpu fast path (GPU viewport-cull + indirect draw) lands behind the same draw() / Facet::ui, so consumers never change — they get GPU-fast for free. That single-seam rule is why the kernel is one crate everyone shares, and why a component's author writes to Scene / Layout and not to any backend. The full 2-category (CPU / CPU+GPU) design is render-design.md.
The headless spine
Because every component's whole observable truth is one Model (Elm) surfaced as state_json (Facet), a test can drive any component with a Msg script and assert the resulting Model/RenderReport — no window, no GPU. Robot testing and the nornir test-matrix are exactly this seam at scale: harness-design.md.