Fuaranfuaran

The source for generative UI

Releases

Fuaran UI ships as a family of host packages, each versioned in its own registry. The project is pre-1.0 – see stability for the compatibility posture.

Surfaces and registries

The machine-readable roster – every host, its package, and its registry – is at /agent/package-matrix.json; the human-readable version is the hosts page. Per-host install steps are in the get-started tracks.

The 0.2 revision – what it added

The current language revision is the 0.2 line, a coordinated pre-1.0 rev taken across every host and the fixture corpus in lock-step (the normative statement is §1.1 of the specification). The author-visible additions:

  • One rename law: scalar value, collection source. A displayed scalar (Metric, LabelValueRow, Fact) is its value; source is reserved for collection feeds (grids, charts, selects). The retired spellings are a hard decode error – a clean break, taken while pre-1.0 allows one.
  • Filters unified with form fields. A filter chip's control is an ordinary form-field kind – including the new dual-thumb Range – and a chip with no value auto-binds to its named filter. The pre-emit validator rejects a decorative filter bar (chips nothing consumes).
  • The declarative floor for forms. A form field may omit its value entirely and auto-bind to $state.<field id> with a typed placeholder – a minimal form is just fields, labels, and a submit.
  • Leaner canonical bytes. A bare JSON string is the canonical literal text form; no-information closure sentinels are off the wire; behavioural flags are omitted when they hold their default.
  • New node kinds. Switch (state-bound conditional composition), Fact (the textual sibling of Metric), Mount (an isolation-boundary for guest subtrees), and the unified Box container – see them rendered live in the component reference.
  • Charts lower to Drawing. Line, bar (grouped and stacked), area, pie/donut, and scatter charts all lower to the bounded typed vector vocabulary – no raw SVG – with keyed mark identity and schema-grounded chart validation at pre-emit time.
  • Compute resolves at render time, everywhere. Transforms and bindings over wire data resolve to the same output across every surface – F#, Python, and Go server rendering, TypeScript hydration, Rust in the browser, and the native Swift / Kotlin projections, which receive an already-resolved tree from the Rust core.

Current .NET release – Fuaran.UI 0.15.0

The .NET host family (Fuaran.UI.*) is at 0.15.0 on NuGet (August 2026), nine recorded revisions on from 0.6.0. The per-change record, with the semver argument for each, is the host's STABILITY.md. The headlines:

  • DateRange (0.7.0). A single-control date-range form-field kind – one field, an ordered start/end pair, validated as a pair rather than as two disconnected dates – in forms and filter bars alike.
  • The types are generated from the language's own definition (0.8.0). The F# structural layer – every node kind, spec record, binding, and action – and the canonical encoder are now generated from a typed interface definition, and the hand-written per-kind encoder is deleted. The wire did not move: the full conformance corpus reproduced byte-identically across the swap. Breaking for code that constructs or matches the wire vocabulary directly; invisible to the smart-constructor authoring surface. The design story is in the vocabulary is data too.
  • Scope × sink render entry and the guest capability seam (0.9.0). Additive: a render entry combining a runtime scope with a telemetry sink (state isolation no longer costs you render-failure events), and GuestSeam – a default-off hook that lets a host gate the runtime handed to mounted guest subtrees.
  • Op-stream verification hardening (0.10.0). Checkpoint snapshots are now hash-verified – position-bound, refused before replay folds a tail over them – the provenance envelope gains its decode leg, DAG verification runs in the browser, and one non-conformant encode path (UpdateState node payloads) was corrected to the canonical form the specification always required.
  • Declared cell tones (0.11.0). A grid cell whose tone is a declared value-to-tone mapping rather than a host closure, which makes a value-conditional tone expressible on the wire at all – its predecessor's two fields were both closures, and no lenient shape can conjure a function. Additive: a tree with no toned cell encodes to exactly the bytes it did at 0.10.0.
  • Typed row sources (0.12.0). Grid and chart feeds leave the residual "<opaque>" sentinel: rows are structured on the wire, and the authoring surface takes an explicit row projection rather than erasing the row type. Breaking for authoring code; wire-additive with read compatibility, since decoders accept the old sentinel indefinitely.
  • Wire resource limits (0.13.0). The host's expression of section 21 of the specification – bounds on node depth, syntactic JSON depth, string length, array length, and total node count, with a typed LIMIT_EXCEEDED refusal. It narrows what the decoder accepts, and that is the point: the totality claim held on semantics and was false on shape, because an unguarded recursive walk over a few hundred kilobytes of opening brackets ended the process rather than returning an error. Which hosts have adopted the limits is recorded on the security page.
  • The dispatch gate fails closed (0.14.0). The published posture is that a capability an emitted tree reaches is denied unless the host allows it. Every shipped runtime returned allow, so an unconfigured host inherited a permissive posture while the claim read as satisfied. The gate now denies, and the same release closed the descriptor set: four wire-survivable actions had been reaching their substrates without consulting the gate at all. The permissive posture stays available but is reached by name – Runtime.permissive, PermissiveRuntime, MutableRuntime.Permissive(), BrowserRuntime.createPermissive(), and the driver and bounded-service equivalents – so one grep enumerates every place the old behaviour is back. The break is behavioural rather than signature-level: a host compiles as before and then refuses the actions it used to perform, which is the loudest safe way for this change to arrive.
  • Guest mounts and custom renderers are isolated (0.15.0). The two surfaces that sit outside the dispatch gate structurally, so the previous release's inversion did not reach them. A decoded mount is clamped to an outbound-only channel, with two-way traffic now a host grant and the downgrade recorded rather than silently applied; a guest whose host installed no capability seam receives a runtime that refuses everything, in place of the host's own runtime unwrapped; and both custom-renderer registries key on the render scope alongside the module and component ids, with no cross-scope fallback, so a tree rendered on a public surface can no longer select a renderer registered for a privileged one. The content-hash check also becomes a host floor a tree may only tighten, closing the bypass where an emission chose its own strictness.

The last two are the security-relevant ones. What they are part of, which host enforces which property today, and what the host still owns are set out on the security page; the semver argument for each is under the recorded breaking-change headings in STABILITY.md.

Changelogs

Per-host changelogs will aggregate here – latest-first and host-badged – as the host repositories adopt structured changelog files. Until then, each host's releases are tracked in its own repository (linked from hosts), and the wire format records the pinned core@1.0 / v2 contract versions that every release upholds.

Email updates

Want the occasional note when something ships? Subscribe to the Fuaran newsletter. The list is run by a dedicated email provider – your address is stored with them, with one-click unsubscribe, and never by this site.