How components can help us govern agents

My most-cited BYTE cover story was 1994’s Componentware, which made the case for a two-tier architecture best exemplified then by Visual Basic and its component ecosystem. The prevailing strategy for software reuse, object-oriented programming, hadn’t gained the traction we all expected. Visual Basic showed us why it hadn’t. Objects were written in the same languages, and by the same specialized coders, as the programs that reused those objects. VB flipped the script. Code-savvy component builders created building blocks that domain-savvy systems thinkers could wire together.

Then the web flipped the script again. The browser was the new canvas, and it left the component ecosystem behind. Plugins came and went. The web platform eventually did define standards for components but they’ve been eclipsed by the web’s de facto standard framework, React, and its component architecture. And just like objects 30 years ago, React components are both produced and consumed by specialized coders. There wasn’t a good way for a modern solution builder to tap into React’s component ecosystem.

The framework that I co-maintain, XMLUI, harks back to the VB model. A UI is defined by concise semantic XML markup that refers to a catalog of components. There is no visual canvas but, as we debated whether or how to recreate that experience, the question became moot. When agents write declarative markup in conversation with us, direct manipulation matters less than it used to.

A better target language for LLMs

It’s no accident that Markdown has become a primary way for humans and AIs to collaborate. Why not HTML and CSS? Markdown constrains AIs to a smaller set of patterns, and that’s a good general rule. Our new agentic team members are powerful but undisciplined. Left to their own devices they behave in unpredictable ways. The fewer degrees of freedom we allow them, the better things will go for all of us.

The same principle applies to coding. When you ask an LLM to build an app with React and CSS, you invite it to operate with few constraints. Nothing stops an agent from writing a useEffect that subscribes to something and then forgets or misuses its cleanup function.

XMLUI automatically endows every component with three life-cycle events, shown in this example.


  

onMount runs once when the component becomes visible. onUnmount runs once when it leaves. onError catches anything either of them throws and receives { source, error }, where source is "mount", "unmount", "beforeDispose", or "action". The agent does not write a return value, does not pick a dependency array, does not name a cleanup function. There is nothing to forget.

We say that XMLUI is to React as Java and C# are to C++: a managed language that abolishes many kinds of errors and vulnerabilities. In both cases there are valid reasons to pierce the abstraction and reach for low-level primitives, but that should be the exception not the rule. If most of what needs doing can happen in a managed layer, it should.

Wrapping React components

XMLUI components are wrappers around React components; they expose properties and APIs for declarative use. The core set of components delivered in the XMLUI runtime handle layout, data access, lists, tables, and UI controls including buttons, switches, and sliders. More advanced components like ECharts, Tiptap, and Masonry are wrapped in the same way and delivered as loadable extensions. All components share a common mechanism for semantic tracing. When enabled, semantic tracing captures a rich history that includes API calls and results, handler timings, and — this is the semantic part — trace events keyed to ARIA labels.

The aria-label property becomes the component’s accessible name in traces, so a screenreader announces “Volume, slider, 50” and the trace records value:change didChange Slider [Volume] "53". This unlocks accessibility, semantic traces that AIs can reason about, and regression tests generated from user journeys.

The wrapper can even make interaction with a observable. When ECharts draws a chart, for example, the browser sees a rectangle of pixels. Click a bar and all the DOM sees is that you clicked a rectangle. The XMLUI wrapper opens the black box by deriving a name for the chart, so the canvas becomes “Revenue by Quarter — bar chart” to a screen reader, a test runner, and a trace. And it bridges ECharts’ own event model into the trace, so a click becomes “series0 → Q2 = 200” and a legend toggle becomes “Series 1: hidden”. The trace no longer says something was clicked, it says what data the user saw.

Agents now often build user interfaces from scratch. An agent receives a prompt, writes React and CSS, and ships something that seems to work. Then comes the unhelpful bug report: “The chart did something weird when I clicked on it.” A UI built from traceable components yields a different kind of report. It says they clicked Q2 on the revenue chart,

[…]
Content was trimmed to protect the source. Please visit the original article for the full text.

This article has been indexed from InfoWorld