Skip to main content
The console is run under Nyuchi. The line is ownership, not naming: the language, its toolchain, its components and its logic are Mzizi IP; the console, paid plans, billing and active cyber testing are Nyuchi’s. The ecosystem page follows it repository by repository.
mzizi-dev/mzizi-console is the Mzizi console, live at app.mzizi.dev. It is a standalone repository, and its scope is the registry, the components, the tokens, the architecture and developer tooling. Today it is Astro in front, with Dioxus islands behind for the data. It reads the registry at https://api.mzizi.dev/v1. It is the one part of Mzizi meant to keep state: accounts, component version history, usage telemetry and the Fundi issue desk belong to it. Today it keeps no database of its own: the repository has no Supabase client, environment variable or migration, its data comes from the public API, and sign-in is WorkOS AuthKit. Decided, not built: any state it keeps goes in Cloudflare D1. See where data lives. The console is where the gated Fundi tools get their signed-in user.

The split

Astro renders the chrome — navigation, headings, prose, the page shell — as static HTML at build time. Today, Dioxus islands render the data, fetched from the registry API at runtime. Mzizi’s own components are Rust, and their render path is Mzizi’s own render(); the rebuild described below replaces them. Both halves are deliberate. The chrome is static because a console’s navigation has no reason to cost a 900 KiB WebAssembly download before it can show a heading; the overview page mounts no island at all and ships no WASM. The data is live because a component list baked in at build time goes stale the moment a component ships, and a stale copy that still looks authoritative is the defect class this ecosystem keeps removing.

Where it is going

Decided, not built (mzizi-console#34):
  • One Rust Worker serves Astro’s output. There is no second service for the chrome.
  • Sign-in moves to the server, through WorkOS, with a session cookie.
  • The data store is Cloudflare D1, for any state the console keeps.
  • It depends on the published Roots crates rather than on a framework’s islands.
Until that work lands, the page above describes what runs today.

Status

app.mzizi.dev is live, behind WorkOS AuthKit sign-in (checked 29 September 2026: the host answers 200). Report a security problem in the console to security@nyuchi.com.

What it replaces

@nyuchi/mzizi-console-app — an earlier mini-app, last at 0.2.0-beta.1, which the Nyuchi Console mounted under /apps/mzizi/*. It was never published to npm and shipped manually. The rewrite makes it a standalone surface at its own domain, and makes it Rust. That follows the documentation-architecture-framework doctrine (“Astro + Vite+ (Capacitor shell)”), which lives in mzizi-dev/mzizi-registry as astro-vite-plus.mdx. At registry commit f10d802 its rules read “The UI is Astro.”, “Underneath is Rust first, TypeScript second.” and “Mzizi’s own surfaces have no third UI framework.” The rewrite also separates the two owners cleanly — Mzizi serves mzizi.dev and api.mzizi.dev; the console serves app.mzizi.dev.

Ported by contract, not translated

The governing rule of the port: a faithful port of a broken component still compiles. Two of the five routes could not have been translated even in principle. Architecture called /architecture/frontend/axes and /architecture/frontend/layers. Both answer 410 Gone in production — checked, not assumed — and have done since the axis model was retired. So the route was rewritten against nodes, rungs and strands. Rungs are listed separately rather than as nodes with an empty backbone, because belonging to neither backbone is the fact the model turns on. See the helix. Tokens was described in the earlier manifest as the “Five African Minerals” palette. There are seven minerals, in a palette of 21 colour families. mzizi-dev/mzizi-registry removed the retired name “Five African Minerals”. Its __tests__/tokens-seven-fold.test.ts fails if that exact name appears in the registry’s tracked files outside its changelog, release records and tests. The guard reads only the registry, so the name survived in a separate repository’s client. That last row matters most. A 410 and an empty registry looked identical, so a permanently broken route presented itself as “no data”.

Three envelope conventions

Measured against production rather than assumed — the API does not use one shape: Assuming a single convention decodes two of the three to nothing, and nothing renders as an empty page rather than as an error.

Verifying a client against the live API

The console’s test suite decodes captured live responses with its production types. That is a different claim from decoding fixtures the repository wrote itself, which prove only that the types are self-consistent — the earlier client’s types were self-consistent and wrong.
The captures are excluded from formatting on purpose: reformatting them would turn bytes the API sent into fixtures the repository wrote.

Size is a deployability requirement

After wasm-opt -Oz, the island bundle is about 1.0 MiB — roughly 921 KiB of WebAssembly plus 74 KiB of JavaScript and 25 KiB of snippets. Optimisation is not a nicety here: an unoptimised debug build of the crate is a single 39.5 MB file, and Cloudflare’s per-asset limit is 25 MiB on every plan, so it would be rejected at deploy. The build script warns loudly rather than silently when wasm-opt is missing, because skipping it does not produce a slightly larger bundle — it produces one that may not deploy at all.