https://blog.jonudell.net/2025/07/18/introducing-xmlui/
Skip to content
Jon Udell
Strategies for Internet citizens
Menu
* index
Introducing XMLUI
18 Jul 202519 Jul 2025 ~ Jon Udell
In the mid-1990s you could create useful software without being an
ace coder. You had Visual Basic, you had a rich ecosystem of
components, you could wire them together to create apps, standing on
the shoulders of the coders who built those components. If you're
younger than 45 you may not know what that was like, nor realize web
components have never worked the same way. The project we're
announcing today, XMLUI, brings the VB model to the modern web and
its React-based component ecosystem. XMLUI wraps React and CSS and
provides a suite of components that you compose with XML markup.
Here's a little app to check the status of London tube lines.
[xmlui2]
A dozen lines of XML is enough to:
* Define a Select and fill its Items with data from an API call.
* Define a DataSource to fetch data from another API call.
* Use the value of the Select to dynamically form the URL of the
DataSource.
* Use a resultSelector to drill into the result of the second API
call.
* Bind that result to a Table.
* Bind fields in the result to Columns.
This is a clean, modern, component-based app that's reactive and
themed without requiring any knowledge of React or CSS. That's
powerful leverage. And it's code you can read and maintain, no matter
if it was you or an LLM assistant who wrote it. I'm consulting for
the project so you should judge for yourself, but to me this feels
like an alternative to the JavaScript industrial complex that ticks
all the right boxes.
Components
My most-cited BYTE article was a 1994 cover story called
Componentware. Many of us had assumed that the engine of widespread
software reuse would be libraries of low-level objects linked into
programs written by skilled coders. What actually gained traction
were components built by professional developers and used by business
developers.
There were Visual Basic components for charting, network
communication, data access, audio/video playback, and image scanning/
editing. UI controls included buttons, dialog boxes, sliders, grids
for displaying and editing tabular data, text editors, tree and list
and tab views. People used these controls to build point-of-sale
systems, scheduling and project management tools, systems for medical
and legal practice management, sales and inventory reporting, and
much more.
That ecosystem of component producers and consumers didn't carry
forward to the web. I'm a fan of web components but it's the React
flavor that dominate and they are not accessible to the kind of
developer who could productively use Visual Basic components back in
the day. You have to be a skilled coder not only to create a React
component but also to use one. XMLUI wraps React components so
solution builders can use them.
User-defined components
XMLUI provides a deep catalog of components including all the
interactive ones you'd expect as well as behind-the-scenes ones like
DataSource, APICall, and Queue. You can easily define your own
components that interop with the native set and with one another.
Here's the markup for a TubeStops component.
{$props.line}
Here's markup that uses the component twice in a side-by-side layout.
It's easy to read and maintain short snippets of XMLUI markup. When
the markup grows to a hundred lines or more, not so much. But I never
need to look at that much code; when components grow too large I
refactor them. In any programming environment that maneuver entails
overhead: you have to create and name files, identify which things to
pass as properties from one place, and unpack them in another. But
the rising LLM tide lifts all boats. Because I can delegate the
refactoring to my team of AI assistants I'm able to do it fluidly and
continuously. LLMs don't "know" about XMLUI out of the box but they
do know about XML, and with the help of MCP (see below) they can
"know" a lot about XMLUI specifically.
Reactivity
If you've never been a React programmer, as I have not, the biggest
challenge with XMLUI-style reactivity isn't what you need to learn
but rather what you need to unlearn. Let's take another look at the
code for the app shown at the top of this post.
Note how the Select declares the property id="lines". That makes
lines a reactive variable.
Now look at the url property of the DataSource. It embeds a reference
to lines.value. Changing the selection changes lines.value. The
DataSource reacts by fetching a new batch of details. Likewise the
Table's data property refers to tubeStations (the DataSource) so it
automatically displays the new data.
There's a name for this pattern: reactive data binding. It's what
spreadsheets do when a change in one cell propagates to others that
refer to it. And it's what React enables for web apps. React is a
complex beast that only expert programmers can tame. Fortunately the
expert programmers who build XMLUI have done that for you. As an
XMLUI developer you may need to unlearn imperative habits in order to
go with the declarative flow. It's a different mindset but if you
keep the spreadsheet analogy in mind you'll soon get the hang of it.
Along the way you'll likely discover happy surprises. For example,
here's the search feature in our demo app, XMLUI Invoice.
[search2]
Initially I wrote it in a conventional way, with a search button.
Then I realized there was no need for a button. The DataSource URL
that drives the query can react to keystrokes in the TextBox, and the
Table can in turn react when the DataSource refreshes.
Found {search.value ? search.value.length : 0} results for
"{searchTerm.value}":
Themes
When the team first showed me the XMLUI theme system I wasn't too
excited. I am not a designer so I appreciate a nice default theme
that doesn't require me to make color choices I'm not qualified to
make. The ability to switch themes has never felt that important to
me, and I've never quite understood why developer are so obsessed
with dark mode. I have wrestled with CSS, though, to achieve both
style and layout effects, and the results have not been impressive.
XMLUI aims to make everything you build look good, and behave
gracefully, without requiring you to write any CSS or CSS-like style
and layout directives.
You can apply inline styles but for the most part you won't need them
and shouldn't use them. For me this was another unlearning exercise.
I know enough CSS to be dangerous and in the early going I abused
inline styles. That was partly my fault and partly because LLMs think
inline styles are catnip and will abuse them on your behalf. If you
look at the code snippets here, though, you'll see almost no explicit
style or layout directives. Each component provides an extensive sets
of theme variables that influence its text color and font, background
color, margins, borders, paddings, and more. They follow a naming
convention that enables a setting to control appearance globally or
in progressively more granular ways. For example, here are the
variables that can control the border color of a solid button using
the primary color when the mouse hovers over it.
color-primary
backgroundColor-Button
backgroundColor-Button-solid
backgroundColor-Button-primary
backgroundColor-Button-primary-solid
backgroundColor-Button-primary-solid--hover
When it renders a button, XMLUI works up the chain from the most
specific setting to the most general. This arrangement gives
designers many degrees of freedom to craft exquisitely detailed
themes. But almost all the settings are optional, and those that are
defined by default use logical names instead of hardcoded values. So,
for example, the default setting for backgroundColor-Button-primary
is $color-primary-500. That's the midpoint in a range of colors that
play a primary role in the UI. There's a set of such semantic roles,
each associated with a color palette. The key roles are:
Surface: creates neutral backgrounds and containers.
Primary: draws attention to important elements and actions.
Secondary: provides visual support without competing with primary
elements.
What's more, you can generate complete palettes from single midpoint
value for each.
name: Earthtone
id: earthtone
themeVars:
color-primary: "hsl(30, 50%, 30%)"
color-secondary: "hsl(120, 40%, 25%)"
color-surface: "hsl(39, 43%, 97%)"
[earthtone]
Themes aren't just about colors, though. XMLUI components work hard
to provide default layout settings that yield good spacing, padding,
and margins both within individual components and across a canvas
that composes sets of them. I am, again, not a designer, so not
really qualified to make a professional judgement about how it all
works. But the effects I can achieve look pretty good to me.
Scripting
As a Visual Basic developer you weren't expected to be an ace coder
but were expected to be able to handle a bit of scripting. It's the
same with XMLUI. The language is JavaScript and you can go a long way
with tiny snippets like this one in TubeStops.
TubeStops does also use the transformResult property of its
DataSource to invoke a more ambitious chunk of code.
function transformStops(stops) {
return stops.map(stop => {
// Helper to extract a value from additionalProperties by key
const getProp = (key) => {
const prop = stop.additionalProperties && stop.additionalProperties.find(p => p.key === key);
return prop ? prop.value : '';
};
return {
name: stop.commonName,
zone: getProp('Zone'),
wifi: getProp('WiFi'),
toilets: getProp('Toilets'),
// A comma-separated list of line names that serve this stop
lines: stop.lines ? stop.lines.map(line => line.name).join(', ') : ''
};
});
}
This is not trivial, but it's not rocket science either. And of
course you don't need to write stuff like this nowadays, you can have
an LLM assistant do it for you. So we can't claim that XMLUI is 100%
declarative. But I think it's fair to say that the imperative parts
are well-scoped and accessible to a solution builder who doesn't
know, or want to know, anything about the JavaScript industrial
complex.
Model Context Protocol
In the age of AI, who needs XMLUI when you can just have LLMs write
React apps for you? It's a valid question and I think I have a pretty
good answer. The first version of XMLUI Invoice was a React app that
Claude wrote in 30 seconds. It was shockingly complete and
functional. But I wasn't an equal partner in the process. I'm aware
that React has things like useEffect and useContext but I don't
really know what they are or how to use them properly, and am not
competent to review or maintain JavaScript code that uses these
patterns. The same disadvantage applies to the CSS that Claude wrote.
If you're a happy vibe coder who never expects to look at or work
with the code that LLMs generate, then maybe XMLUI isn't for you.
If you need to be able review and maintain your app, though, XMLUI
levels the playing field. I can read, evaluate, and competently
adjust the XMLUI code that LLMs write. In a recent talk Andrej
Karpathy argues that the sweet spot for LLMS is a collaborative
partnership in which we can dynamically adjust how much control we
give them. The "autonomy slider" he envisions requires that we and
our assistants operate in the same conceptual/semantic space. That
isn't true for me, nor for the developers XMLUI aims to empower, if
the space is React+CSS. It can be true if the space is XMLUI.
To enhance the collaboration we provide an MCP server that helps you
direct agents' attention as you work with them on XMLUI apps. In MCP
is RSS for AI I described the kinds of questions that agents like
Claude and Cursor can use xmlui-mcp to ask and answer:
Is there a component that does [X]?
What do the docs for [X] say about topic [Y]?
How does the source code implement [X]?
How is [X] is used in other apps?
You place the xmlui-mcp server alongside the xmlui repo which
includes docs and source code. And the repo in which you are
developing an XMLUI app. And, ideally, other repos that contain
reference apps like XMLUI Invoice.
Working with LLMs
This arrangement has mostly exceeded my expectations. As I build out
a suite of apps that exemplify best practices and patterns, the
agentic collaboration improves. This flywheel effect is, of course,
still subject to the peculiar habits of LLM assistants who constantly
need to be reminded of the rules.
1 don't write any code without my permission, always preview proposed
changes, discuss, and only proceed with approval.
2 don't add any xmlui styling, let the theme and layout engine do its
job
3 proceed in small increments, write the absolute minimum amount of
xmlui markup necessary and no script if possible
4 do not invent any xmlui syntax. only use constructs for which you
can find examples in the docs and sample apps. cite your sources.
5 never touch the dom. we only use xmlui abstractions inside the App
realm, with help from vars and functions defined on the window
variable in index.html
6 keep complex functions and expressions out of xmlui, they can live
in index.html or (if scoping requires) in code-behind
7 use the xmlui mcp server to list and show component docs but also
search xmlui source, docs, and examples
8 always do the simplest thing possible
It's like working with 2-year-old savants. Crazy, but it can be
effective!
To increase the odds that you'll collaborate effectively, we added a
How To section to the docs site. The MCP server makes these articles
visible to agents by providing tools that list and search them. This
was inspired by a friend who asked: "For a Select, suppose you don't
have a static default first item but you want to fetch data and
choose the first item from data as the default selected, how'd you do
that in xmlui?" It took me a few minutes to put together an example.
Then I realized that's the kind of question LLMs should be able to
ask and answer autonomously. When an agent uses one of these tools it
is anchored to ground truth: an article found this way has a citable
URL that points to a working example.
It's way easier for me to do things with XMLUI than with React and
CSS, but I've also climbed a learning curve and absorbed a lot of
tacit knowledge. Will the LLM-friendly documentation flatten the
learning curve for newcomers and their AI assistants? I'm eager to
find out.
Content management
We say XMLUI is for building apps, but what are apps really? Nowadays
websites are often apps too, built on frameworks like Vercel's
Next.js. I've used publishing systems built that way and I am not a
fan. You shouldn't need a React-savvy front-end developer to help you
make routine changes to your site. And with XMLUI you don't. Our demo
site, docs site, and landing page are all XMLUI apps that are much
easier for me to write and maintain than the Next.js sites I've
worked on.
"Eating the dogfood" is an ugly name for a beautiful idea: Builders
should use and depend on the things they build. We do, but there's
more to the story of XMLUI as a CMS. When you build an app with XMLUI
you are going to want to document it. There's a nice synergy
available: the app and its documentation can be made of the same
stuff. You can even showcase live demos of your app in your docs as
we do in component documentation, tutorials, and How To articles.
I was an early proponent of screencasts for software demos, and it
can certainly be better to show than tell, but it's infuriating to
search for the way to do something and find only a video. Ideally you
show and tell. Documenting software with a mix of code, narrative,
and live interaction brings all the modalities together.
Extensibility
Out of the box, XMLUI wraps a bunch of React components. What happens
when the one you need isn't included? This isn't my first rodeo. In a
previous effort I leaned heavily on LLMs to dig through layers of
React code but was still unable to achieve the wrapping I was aiming
for.
For XMLUI the component I most wanted to include was the Tiptap
editor which is itself a wrapper around the foundational ProseMirror
toolkit. Accomplishing that was a stretch goal that I honestly didn't
expect to achieve before release. But I was pleasantly surprised, and
here is the proof.
[tiptap]
This XMLUI TableEditor is the subject of our guide for developers who
want to understand how to create an XMLUI component that wraps a
React component. And isn't just a toy example. When you use XMLUI for
publishing, the foundation is Markdown which is wonderful for writing
and editing headings, paragraphs, lists, and code blocks, but awful
for writing and editing tables. In that situation I always resort to
a visual editor to produce Markdown table syntax. Now I have that
visual editor as an XMLUI component that I can embed anywhere.
The React idioms that appear in that guide were produced by LLMs, not
by me, and I can't fully explain how they work, but I am now
confident it will be straightforward for React-savvy developers to
extend XMLUI. What's more, I can now see the boundary between
component builders and solution builders begin to blur. I am mainly a
solution builder who has always depended on component builders to
accomplish anything useful at that level. The fact that I was able to
accomplish this useful thing myself feels significant.
Deployment
Here's the minimal XMLUI deployment footprint for the TableEditor.
TableEditor
+-- Main.xmlui
+-- index.html
+-- xmlui
+-- 0.9.67.js
The index.html just sources the latest standalone build of XMLUI.
Here's Main.xmlui.
{ markdown }
You can use any static webserver to host the app. You can even run it
from an AWS bucket.
For XMLUI Invoice we provide a test server that includes a
localhost-only static server, embeds sqlite, and adds a CORS proxy
for apps that need that support when talking to APIs (like Hubspot's)
that require CORS. You may need to wrap similar capabilities around
your XMLUI apps but the minimal deployment is dead simple.
Web development for the rest of us
XMLUI was conceived by Gent Hito who founded /n software and CData.
The mission of /n software: make network communication easy for
developers. For CData: make data access easy for developers. And now
for XMLUI: make UI easy for developers.
"We are backend people," Gent says. "All our components are
invisible, and when we tried to build simple business UIs we were
surprised to find how hard and frustrating that was."
Those of us who remember the Visual Basic era know it wasn't always
that way. But the web platform has never been friendly to solution
builders who need to create user interfaces. That's become a game for
specialists who can wrap their heads around an ongoing explosion of
complexity.
It shouldn't be that way. Some apps do require special expertise. But
many shouldn't. If you are /n software, and you need to give your
customers an interface to monitor and control the CoreSSH Server, you
shouldn't need to hire React and CSS pros to make that happen. Your
team should be able to do it for themselves and now they can.
I'm having a blast creating interfaces that would otherwise be out of
my reach. Will you have the same experience? Give it a try and let us
know how it goes!
Share this:
* Click to email a link to a friend (Opens in new window) Email
* Click to share on X (Opens in new window) X
* Click to share on Facebook (Opens in new window) Facebook
* Click to share on Reddit (Opens in new window) Reddit
*
Like this:
Like Loading...
Posted in .
[24c273e]
Published by Jon Udell
View all posts by Jon Udell
Post navigation
< PreviousMCP is RSS for AI
4 thoughts on "Introducing XMLUI"
1. [a984e35] Dan says:
19 Jul 2025 at 7:22 pm
This looks intriguing! How is it licensed? (My apologies if the
info was staring me in the face and I just overlooked it.)
Loading...
Reply
1. [24c273e] Jon Udell says:
20 Jul 2025 at 11:04 am
Open source, MIT. If you are able to make something useful
with it I would love to hear about that.
Loading...
Reply
2. [9196fc6] no dice says:
20 Jul 2025 at 7:23 am
"man I wish I could do this in xml" - said nobody ever in 15
years
Loading...
Reply
3. Pingback: Anonymous
Leave a ReplyCancel reply
Search for: [ ] [Search]
* All Posts
* Hypothesis annotations
* Bio
Follow Blog via Email
Enter your email address to follow this blog and receive
notifications of new posts by email.
Email Address [ ]
Follow
Feed
RSS feed RSS - Posts
Creative Commons License
Strategies for Internet Citizens by Jon Udell is licensed under a
Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported
License.
* index
Powered by WordPress.com.
Discover more from Jon Udell
Subscribe now to keep reading and get access to the full archive.
Type your email... [ ]
Subscribe
Continue reading
%d