Spokes.wiki Search About

Synthesis — UI Frameworks

The evolving thesis. This spoke was spun out on 2026-07-10 to give a home to a class of sources that kept arriving with nowhere to route: application-level UI frameworks, component libraries, and design systems. Two of them — a terminal-UI core (opentui) and a web design system (astryx) — had been parked in the hub _inbox; when a third UI-library stray would have made three, the router surfaced the spin-out and the human approved seeding the spoke with these two. (The HTTP-client stray, Ky, stayed parked: it's a runtime library but not UI.)

Why this is a spoke — the negative-space origin

The founding fact is a boundary, not a topic the family already loved. These sources were repeatedly held out of two neighbors:

Current thesis

1. One architecture, many surfaces

The founding pair look unrelated — a Zig terminal core vs. a Meta web design system — but they're two rungs of one stack: a rendering core → reconciler → framework → design system. opentui exposes the lower rungs explicitly (native Zig core + C ABI, with React/Solid reconcilers on top), proving the declarative-components-over-a-render-core model isn't web-specific — the same React mental model drives a terminal. astryx occupies the top rung: it doesn't render anything new, it's an opinionated, themed component + design-token library on top of React. That OpenTUI can also render its component tree to a browser via WebGPU is the sharp version of the claim: the surface is becoming a swappable back-end for a single UI description (terminal, GPU-canvas, DOM), so "terminal UI" and "web UI" are converging toolkits, not separate disciplines.

flutter (2026-07-16) is the native/mobile rung the founding pair lacked, and it pushes the surface-as-swappable-back-end thesis to its limit: rather than adapt to each platform's UI toolkit, Flutter owns the canvas — it renders every pixel itself through its own engine (Skia/Impeller) — so one Dart widget tree paints identically on iOS, Android, web, and desktop. It's also a clean second instance of the reconciler rung: Flutter's persistent element tree diffing an immutable widget tree is the same machinery as opentui's React/Solid reconcilers, under Flutter's own names. So the "one architecture, many surfaces" claim now spans terminal ↔ web ↔ native, with three different answers to who owns the pixels (the terminal grid, the DOM, and — Flutter — the framework itself).

people-in-space (2026-07-26) splits that claim in two. John O'Reilly's KMP sample runs Compose Multiplatform on Android, Wear OS, desktop and Kotlin/Wasm web from one codebase — four surfaces, one component model, which is the thesis holding. Then it writes the iOS client in SwiftUI by hand over the same shared Kotlin. So the repo that best demonstrates surface-independence also declines it on one platform, and does so without apology.

The distinction that falls out is where the sharing stops, and it's a second axis alongside "who owns the pixels":

Neither source pays for its choice: a demo app reports no maintenance or performance cost either way. What the sample does establish is that "one description, many surfaces" and "native UI per platform" aren't rival camps so much as a dial, and a canonical KMP reference (cited by JetBrains' own docs) sets that dial in the middle.

flutter-3-44 (2026-07-28) prices the canvas bet. A release-level view of Flutter shows what "own every pixel" obliges: Impeller Vulkan cache and sync work, signed-distance functions to fix aliasing, shader-uniform binding by name, and accessibility re-implemented per surface (prefers-reduced-motion on web, aria-description on form errors, iOS motion preferences), all behavior a DOM-based framework inherits for free. Hybrid Composition++ is the admission in the other direction: an opt-in Android path using SurfaceControl to composite native views into the Flutter surface, for the pixels Flutter doesn't own after all. Owning the canvas isn't a one-time architectural choice, it's a standing obligation to rebuild the platform's behavior on every platform.

1b. The stack's top rung comes unbundled

flutter-3-44 freezes Material and Cupertino at their final in-framework versions and moves them to standalone material_ui / cupertino_ui packages. Flutter is the one source here that shipped framework and design system fused in a single artifact; astryx was always a layer on React, opentui is the rungs below a design system. So the stack model this spoke proposed gets confirmed from an odd angle — not by a new source fitting it, but by the outlier separating along exactly the seam the model drew, and paying a dependency to do it. The test of whether the split was real: do material_ui and cupertino_ui actually ship on their own cadence, or keep releasing in lockstep with the framework anyway?

2. Agent-ready as the convergent design goal — agent-ready-ui

The non-obvious thing the two share is intent toward AI agents. astryx is "built for how we build now — by people and the agents working alongside them," with API/docs/CLI designed so humans and agents build identically; opentui ships agent-skill support and is the UI layer of the OpenCode agent. From opposite ends of the stack, both bet that a UI toolkit's next audience is a coding agent — and that the old virtues (consistency, accessibility, predictable APIs) are exactly what make a toolkit machine-legible. This is the spoke's live thesis and its seam to ../agentic-tooling-wiki: there, agents emit UI (generative UI, arrow-js/openui); here, the toolkit is the target an agent builds against.

flutter-3-44 moves this from intent to mechanism. Three things a framework did because the builder is an agent: Agentic Hot Reload (an agent connects to a running app and reloads it — handing over the inner loop, not just the source tree), MCP tool definitions consolidated to cut agent token cost (an API-shape decision with a price attached), and packaged Agent Skills for Dart/Flutter — the same unit opentui ships, which makes two independent toolkits converging on skills. The same release also ships GenUI, where agents compose UI at runtime via the A2UI protocol; that half belongs to ../agentic-tooling-wiki, and it's notable mainly because one vendor is now building both sides of the seam at once.

The vocabulary was one framework's all along (added 2026-08-22)

svelte was ingested as the second member of coverage edge 4 and did something a third React-like framework would not have: it made the spoke notice its own words.

This wiki has described opentui, astryx and flutter in terms of reconcilers, renders and rebuilds — the vocabulary react supplied when it was paged as the baseline. Svelte has no reconciler. A compiler works out at build time which DOM depends on which state and emits the update code, so nothing re-runs a component and nothing diffs a tree. The two most-used component frameworks on the web share no mechanism, only a job. So "which reconciler does it use" is not a neutral question about a UI toolkit; it is React's question, and asking it of Svelte returns nothing.

The other departure is where the API lives. Svelte 5's runes — $state, $derived, $effect and four more — are "symbols that you use … to control the Svelte compiler": keywords, not functions. You cannot import one, store one in a variable or pass one as an argument, and they are valid only in certain syntactic positions. React's hooks are ordinary functions whose rules are enforced by convention and a linter; Svelte's equivalents are enforced by a compiler that refuses to build. Every other toolkit here is a library you call. This one is a dialect you compile, and that is a different kind of commitment for a codebase to make.

The bill is legible in the docs' own caveats, which is why they are worth keeping: class instances are not proxied, $state.raw gives up mutation to skip deep reactivity, $state.snapshot exists because the proxy leaks into libraries that do not expect it, and reassignable exported state cannot cross a module boundary because the compiler works one file at a time. Runtime diffing works on whatever value you hand it; build-time analysis needs shapes it can see through.

Two smaller consequences. It puts a second compile-first framework beside flutter — same instinct, opposite surface, and only one of the two brings its own rendering engine. And it sharpens the middle-of-the-stack question from the other side: shadcn-ui made "what a design system sits on" an install-time flag, while Svelte makes it a compile-time fact, so the copy-into-your-repo trick that works for React components has no equivalent here.

Still no outside evidence. Both members of this comparison are first-party documentation, and Svelte's only performance claim is "lean, tightly optimized" with no number attached. Nothing in the corpus measures either framework against the other, so the comparison above is architectural and should not be read as a verdict. That is the standing caveat, and this ingest did not touch it.

Open questions

Sharing at build time, and nothing left at runtime (2026-09-01)

mitosis adds a third answer to where the sharing stops, and it is the one the axis was missing. flutter shares at runtime by owning the canvas. compose-multiplatform in people-in-space shares at runtime per platform, four surfaces in and one out. Mitosis shares only at build time: one component written in a static subset of JSX, parsed to "a simple JSON structure", then emitted as native Angular, React, Qwik, Vue, Svelte, Solid or React Native source. Nothing of Mitosis survives into the artifact — no runtime, no adapter, no version boundary.

On the who owns the pixels axis it is the first entry that owns none and never runs, and it reads as svelte's move taken one step further: Svelte deleted the reconciler by resolving state-to-DOM dependencies at compile time; Mitosis compiles not to DOM operations but to another framework's source. The spoke's compile-away-versus-ship-a-runtime distinction now has a case where the compiler targets the frameworks themselves.

The price is stated nowhere. What can be written once is bounded by what every target can express — hence the static JSX subset — and the docs publish no per-target maturity, no stable/beta/alpha labels, no comparison of generated output against hand-written output. So "compiles to every framework" is, for any particular framework, untested here. That belongs beside growth edge 9: the spoke's central mechanism distinction still has no measured consequence anywhere in the corpus.

It also argues the case this spoke had listed as missing. Coverage edge 6 wanted the web-components story; Mitosis supplies the prosecution — no native server-side rendering, no real integration with a framework's own features such as React context, and "their own rendering libraries and dependencies" riding along. The defence is still absent, and now the edge is asymmetric rather than empty.

The distribution tension gets a third position

astryx ships a package so one change reaches 13,000+ apps. shadcn-ui refuses to be a package and copies source into your repository. Mitosis generates the copies — same conclusion as shadcn/ui that what a developer should receive is their own framework's code, but reached for a different reason and paid for differently: the copies are regenerated from a source of truth rather than forked away from one, and the price moves from upgrade path to expressiveness, since the shared dialect can only contain what all targets support.

The use case that makes this concrete is the one the spoke had only stated abstractly: an organization big enough to standardize its UI is rarely uniform enough to have standardized its frameworks, so a design-system has to exist several times over. The README's own example is Deutsche Bahn's DB UX Design System, with a Figma integration to keep the source of truth upstream of all of them.

A maintenance shape worth watching

14,055 stars, 1,909 commits, and 11 commits in the three months to 2026-09-01, the last on 2026-07-21. Four of the last five human commits come from the UX Engineering Lead of the DB UX Design System — the downstream consumer the README cites — who has 2,673 commits in that project, and a second Mitosis contributor is in that project's top five too. The README asks for contributors outright. One reading is a vendor stepping back and its largest consumer keeping the compiler alive; another is a tool that has reached the shape it needs. Eleven commits cannot separate them, and it is the first time this spoke has a source whose maintainers are moving rather than its features.

Growth edges

Ranked; each names the kind of source that would close it (see ../QUALITY.md → Growth edges).

  1. A number behind "agent-ready." The category now has content (hot reload, token-costed tool surface, packaged skills) and no evidence any of it works — every claim is the vendor's. — needs: a T1/T2 measurement of an agent building against an agent-ready toolkit versus a plain one.
  2. Where the surface-independence ceiling actually sits. people-in-space stopped at iOS and wrote SwiftUI — a preference, not a rendering limit. — needs: a T2 project report or post-mortem that says what the shared-code ceiling cost, in either direction.
  3. The middle of the stack, beyond one framework. flutter fills the application-framework rung alone. — needs: a T1/T2 source on a second full application UI framework, for a comparison rather than a data point.

Coverage edges (added 2026-08-08, at the curator's request for a wider backlog). These widen what the spoke covers instead of answering an open question above; one ordinary solid source closes any.

  1. The web's incumbent component frameworks. Thirteen pages and not one of React, Vue, Svelte, Solid or Angular. Two-fifths closed — react 2026-08-15 (the reconciler baseline) and svelte 2026-08-22, which supplied the comparison rather than another data point: the two share no mechanism at all. — still needs: an independent write-up rather than first-party docs, which is now the whole of what this edge is missing. Vue, Solid and Angular would widen the sample; they would not fix that both members are the vendor describing itself.
  2. The CSS layer. Tailwind and the utility-class argument, plus CSS-in-JS and the newer native features (container queries, :has()), are absent, so design-system has no styling substrate under it. — needs: T2 documentation or a written-up migration.
  3. Web components as the standards-track answer. Lit and the custom-elements story are the one option that outlives framework churn, and the spoke never states the case for or against. Half-stated 2026-09-01, from the hostile side: mitosis exists partly to avoid them and names three reasons — no native server-side rendering, no real integration with framework features such as React context, and bundled rendering libraries and dependencies. That is a competitor's case, made in its own marketing. — still needs: the defence — spec-level docs or a production report from someone who chose web components and can say what it bought them.
  4. Accessibility as a property of a toolkit. No page treats a11y as something a framework gives you or costs you, which is the property teams are legally obliged to care about. — needs: WCAG-level guidance or an audit comparing toolkits.
  5. What copying costs after a year. New 2026-08-18 with shadcn-ui, and it is the evidence the tension above needs. Copied components have no upgrade path by design; imported ones have no escape hatch by design. Nobody in this corpus has reported what happens next — how much drift a copied set accumulates across a codebase, or how often an imported set gets forked anyway. — needs: a T2 engineering write-up or migration post-mortem from a team that ran one arrangement long enough to say, ideally one that switched.
  6. One framework against another, measured. HALF CLOSED 2026-09-03 (research pass) by js-framework-benchmark (T2) — an independent party running 186 implementations of one specified app in Chrome under WebDriver, which is a third-party number on both frameworks and the first the spoke has held on any of them. It settles the mechanism question and sizes it smaller than the marketing: 9.7 KB brotli against 51.4 KB, within a few milliseconds on almost every operation, and 7× apart on exactly one — swapping two rows in a keyed list, where a reconciler has to prove almost nothing changed. react-compiler-hooks measures 90.4 ms on that same swap against plain hooks' 89.9, so the React Compiler does not touch it. svelte's standing "nobody has measured this" claim is retracted on the page. Original text: neither svelte nor react nor flutter is held here with a third-party number attached, so the spoke's central distinction is entirely a claim about mechanism with no measured consequence. 9a. The half that is still open: an application, not a table. New 2026-09-03, the residue of the above. The edge asked for a comparison "on the same application" and what arrived measures DOM throughput under adversarial list mutation — no routing, no data fetching, no forms, no code splitting, no third-party components, no team. Every implementation is also written by someone who wants their framework to win, and Krause states he cannot audit all 186. So the spoke now knows what each update path costs when that path is the whole program, and still nothing about what either choice costs a product. — needs: a migration post-mortem or engineering write-up from a team that shipped the same product on both, with bundle size or interaction latency stated. T2. This is the same shape as edge 8 (what copying costs after a year) and the two may close together. HALF CLOSED 2026-10-05 (research pass) by strawberry-react-to-svelte (T3): a team that shipped one product, a desktop browser's UI, on React for a year and then on Svelte. It reports new-tab first contentful paint 300 → 124 ms and re-renders during token streams cut 10×. Not struck, because the figures come with no method and the workload is the extreme case for a reconciler: six live React roots at once, each re-rendering on every streamed token. That is the swap-a-row operation js-framework-benchmark found 7× apart, repeated all day. So the benchmark's one large gap now has a product behind it, and the edge's wider question is still open. 9b. A migration measured with a method, or reported a year later. New 2026-10-05, the residue of 9a. The one product comparison the spoke holds is the vendor's own launch story, with no tool, device or run count, and it says nothing about ecosystem, hiring or upkeep after the switch. — needs: a migration write-up that states how its numbers were taken, or a follow-up from a team a year after switching, in either direction. T2. Overlaps edge 8.

Contradictions / tensions

The first internal one, 2026-08-18: how a design system reaches its consumers. astryx and shadcn-ui give opposite answers, both from a position of scale.

A third position arrived 2026-09-01: mitosis generates the copies, from one source, in each framework the organization actually uses. It agrees with shadcn/ui that the developer should end up with their own code and with Astryx that a single source of truth is the point — which is why it is a position rather than a compromise, and why its cost lands somewhere else entirely: not upgrade path, not escape hatch, but expressiveness, since a component can only use what every target framework can express.

Neither is wrong about its own goal, and that is what makes it a tension rather than an error. They disagree about whether a design system's value survives being modified. Astryx's answer is that uniformity is the product, so the components stay behind a version boundary and extension happens through composable internals. shadcn/ui's answer is that the defaults are the product and the code is yours, so a fix upstream reaches nobody who already installed it. The corpus has no source measuring what either choice costs after a year — recorded as growth edge 8 below.

The older caveat still holds for both: these are first-party sources, so "performance", "agent-ready" and "consistency at scale" are all self-reported and await outside evidence.

Cross-spoke adjacency

Index — UI Frameworks Wiki

Catalog of every page, grouped by schema.org @type. Spine: synthesis (thesis), log.md (history), this file (catalog). Spun out of the hub _inbox ui-frameworks cluster on 2026-07-10 (OpenTUI + Astryx). Some wiki-links resolve to entity nodes in sibling spokes (intentional cross-wiki links, e.g. meta).

DefinedTerm (concepts)

SoftwareApplication

Dataset (sources)

SoftwareSourceCode (sources)

BlogPosting (sources)

TechArticle (sources)

Person

Organization

Synthesis


Bridge nodes (live in sibling wikis, linked cross-wiki)

meta (../business-messaging-wiki) · google (../llm-providers-wiki — maker of flutter) · vercel (../cloud-wiki — employer of shadcn) · dart (../programming-languages-wiki — Flutter's language) · flame-engine (../game-engines-wiki — built on Flutter)