Rust first
- Rust is the lead. Where a Rust implementation of a component exists, it is the one to use, and these docs present it first.
- The React build keeps working. The React and TypeScript (
.tsx) components stay in the registry and stay installable. They are deprioritised: not the lead, and not where new work goes. These docs call them the React build. - UI and server. Roots covers the handlers that serve a component as well as the component, which is the charter’s full-stack shape for Phase 1.
How Roots relates to the language
Roots components are written in Rust today, not in Mzizi. The language cannot produce them yet: no component lowers to Rust (aservice does, to a local axum package, and a program, to a
dependency-free Rust package), and Phase 1
waits on the benchmark (Status).
Roots is built to support the language: it is meant to be the language’s component model,
the way React is JavaScript’s, with Rust as the platform underneath. When the language
lowers components to Rust, Roots is its target: the RFC writes every Roots contract in the language’s
contract … end grammar. That is a design intention, gated on the benchmark like the rest
of Phase 1.
Until then, the components also do a second job. The registry’s components, React and Rust
together, are the ground truth for the benchmark’s UI tasks. The nine
primitives are hand ports of registry components, and the benchmark scores a
candidate against a component’s Rust reference. That is one of the components’ jobs, not
what they are, and not the benchmark’s goal, which is Mzizi against the best existing
language for each kind of task (the benchmark).
What exists today
The Rust half of the registry lives inmzizi-rs/ in
mzizi-dev/mzizi-registry, a Cargo workspace.
All fourteen of its crates are on crates.io at 0.7.0 (checked 4 November 2026): eight node
crates, one per node that has Rust, two umbrella crates that re-export them, and four
supporting crates (mzizi-harness, mzizi-data, mzizi-mongodb and mzizi-activitypub). The
crates move together. 0.1.0 was the first release (29 September 2026); 0.2.0 and 0.3.0 were
published on 7 October 2026, 0.4.0 on 20 October for registry release v4.9.0, 0.5.0 with
registry release v4.16.0, 0.6.0 with v4.17.0 (published 25 October 2026) and 0.7.0 on 1 November 2026. 0.4.0 was
breaking for code that builds or matches Inline::Link (links now carry a title) or
ListItem::children (now Vec<ListChild>), and 0.5.0 was breaking for mzizi-mongodb,
which refuses cross-collection $lookup, $graphLookup and $unionWith in aggregate (use
aggregate_joining) and returns Zeroizing wrappers from Uri::password and
scram::salted_password. The registry’s changelog has each release in full.
The render path. The components are Mzizi’s own, not borrowed from another framework. Their
render path is moving to Mzizi’s own render(props) -> String: registry
#506 and
#510 are merged, with a skeleton and six
static primitives. Dioxus is out of the stack (owner, 4 November 2026). The crates
published on crates.io (0.7.0) still depend on it, in mzizi-ui, mzizi-brand, mzizi-shell,
mzizi-docs and mzizi-roots, and the table below describes them as published. Removing it is
tracked in mzizi-registry#635; what
renders the Rust components once it is gone is not decided, and this page does not say.
Install
mzizi-roots has the features ui, brand
and shell, and always includes mzizi-tokens. mzizi-roots-server has assurance,
fundi, docs and discovery; docs brings in the UI dependency that is being removed, because mzizi-docs also carries
two documentation renderers. To take less, turn the defaults off and name what you need, or
depend on a single node crate:
cargo add takes the newest release, 0.7.0. To write the dependency by hand, use the
requirement the crate READMEs use:
The first batch: twelve brand components
The first Roots batch converts twelve N3 brand components, where there was no Rust at all before:mzizi-alert-banner, mzizi-avatar-stack, mzizi-cover-header, mzizi-empty-state,
mzizi-escalation-card, mzizi-gauge-card, mzizi-hero-stat, mzizi-meta-tile,
mzizi-stats-row, mzizi-success-screen, mzizi-suitability-card and mzizi-user-card.
They ship in mzizi-brand.
Each one carries a contract, checked against its rendered output. The contract has two
parts. The registry contract is the one every component has: one name, one set of variants,
the same data-slot, data-portal and tokens as the React build, asserted against the
.tsx sibling. On top of that, each module exports clauses in the language’s
contract … end grammar, three to eight per component and 65 in all. The crate’s contract
suite renders each component and evaluates every clause against the markup
it emits. A clause it cannot evaluate fails. For example, from mzizi-alert-banner:
mz contract. The
language’s own evaluator checks a .mz component against itself and cannot read Rust.
The ports also fix six defects the React build still has, such as a 40px button under the
48px touch floor and an unclamped aria-valuenow. Each fix has a test.
The Markdown renderer
mzizi-ui carries MarkdownRenderer from 0.2.0. It shows Markdown, including text written by
other people, safe by construction: it parses the text into a typed tree of blocks and
inlines and renders that tree as UI elements. There is no HTML string anywhere, so there is
no dangerous_inner_html to get wrong.
Its props include content, links (a MarkdownLinks) and from (a MarkdownSource), and
mzizi-roots re-exports mzizi-ui as mzizi_roots::ui through its default ui feature. A
usage example is left out while the Rust render path is being replaced (owner, 4 November 2026);
the source is at /v1/rs/markdown-renderer.
With cargo add mzizi-ui instead, import from mzizi_ui directly.
- Raw HTML is text.
<script>,<img onerror>and<a href>in the source show as written. - Links pass an allow-list. By default (
MarkdownLinks::Safe) http, https, mailto, tel and relative addresses are kept;MarkdownLinks::Httpskeeps https only. From0.3.0, an address with whitespace or a control character inside is refused, and a web address needs a host and no credentials, sohttps://bank.example@evil.exampleis refused. A refused link keeps its words and loses its address. http and https links open in a new tab withrel="noopener noreferrer". - Rich text.
from: MarkdownSource::Html(orAuto) reads an editor’s HTML into the same tree with a small reader that builds plain data, never a DOM. From0.3.0a nested list stays nested and<ol start>keeps its first number. heading_baseshifts#headings under a page’s own headings.- Hostile text stays linear. Each inline parse has a scanning budget, and nesting is bounded.
contracts/ui/markdown-renderer
(1.1.0): the React build and a pure Astro build are held to the same states, including a hostile
one, and the TypeScript and Rust suites run the same 55 shared cases. The Astro build installs
from the registry (mzizi add markdown-renderer --target astro); the contract names
@bundu/ui/MarkdownRenderer.astro from @bundu/ui 0.6.0, which is not on npm yet (0.5.0 was
the latest on 7 October 2026). The Rust source is at
/v1/rs/markdown-renderer, which names
mzizi-ui, and api.mzizi.dev serves the safe React and Astro builds too.
Reading the Rust source
You can read a component’s Rust source over the API:crate field names the crate its component ships in, so it answers which one to
depend on:
9b86e03 on, /v1/rs/{name} serves all twelve brand components, each
naming mzizi-brand, alongside the primitives in mzizi-ui, the app chrome in mzizi-shell
and the server rungs in their own crates. On 30 September 2026 the API was built from that
commit, and so was the MCP server. Both pins move, so read the live one from
the source: the API’s x-mzizi-source header, or the MCP server’s catalogue.json.
The MCP server is Rust first too: mzizi_get_component leads with the component’s crate,
its cargo add line, its contract and its .rs source, then gives the pure Astro build where
there is one (from mzizi-mcp 0.12.0), and the React build last.
Where to go next
The registry
How the registry works, and how to install from it today.
The helix
The DNA-helix architecture every component, Rust or React, is placed on.
Browse the components
Every component, grouped by node, at
mzizi.dev/components.The MCP server
Read any component, its tokens and its doctrine from an agent.