The reference renderer (write your own in a day)
Writing a renderer has looked like an open-ended commitment. It is not: the wire is bounded, the Core level is small, and there is now a minimal, dependency-free reference renderer you can read in one sitting and start from.
It lives at frontend/reference-renderer/ — one HTML file and one JS module, no framework and no
build step. It renders a Mateu UI using nothing but the wire itself, which is exactly why it is the
concrete proof of portability: if a ~250-line file with no
dependencies can render the definition, the definition is genuinely portable.
Run it
Section titled “Run it”cd frontend/reference-rendererpython3 -m http.server 8090# open http://localhost:8090, set Backend to a running Mateu app (any Java/.NET/Python server), pick a routeThe whole protocol, in four steps
Section titled “The whole protocol, in four steps”A renderer is a function from UIIncrementDto to painted UI plus a way to post actions back. That is
all:
- One call.
POST {backend}/mateu/v3/sync/{route}(route in the path,_no_routewhen empty) with a body of{ route, actionId, componentState, appState, parameters, … }. The route load isactionId: "". The response is aUIIncrementDto(see the wire specification). - Apply the envelope. Run
commands(SetWindowTitle,navigateTo, …), showmessages, then apply theReplacefragments. - Walk the tree. Each node’s real type is
metadata.type; aCard’s content is inmetadata.content; aFormFieldcarriesfieldId/label/dataType/stereotype/options; values come from the fragmentstate/initialData. - Post actions back. A button posts its
actionIdwith the currentcomponentState; the response is another increment, applied the same way.
Reaching Core, then stopping (or not)
Section titled “Reaching Core, then stopping (or not)”Core is a usable renderer: forms, field types, validation, actions, CRUD listings, text. When every
Core fixture renders with no <mateu-unsupported> placeholder, you are Core-conformant — a legitimate,
complete answer. Standard (sections, tabs, zones, wizards, filtering, master-detail) and Full (charts,
uploads, islands, adapters) are where you keep going if you want to.
Declare what you support (SUPPORTED_TYPES in the module) so the report can tell “this type is not
supported” apart from “this type broke” — only the second is a bug.
Scope & honesty
Section titled “Scope & honesty”This is a teaching / proof artifact, not a first-party product renderer. It implements Core; it
does not do overlays (Add fragments), the full command set, the client fetch plan for external REST
sources, or the rich catalogue. The first-party conformance harness
drives renderers built on the shared libs/mateu plumbing; this standalone renderer shows the wire→DOM
mapping directly, and wiring it into that harness is a follow-up. See frontend/reference-renderer/README.md.