xoong
Build data-driven web pages with HTML, plain CSS and your OpenAPI document. Custom elements in the Light DOM, no virtual DOM, no runtime dependencies in the core, no build step needed to try it.
What you write
A screen is HTML. The table below reads listPeople from an OpenAPI operation; sorting, search, paging, selection, the confirm dialog and the toast are attributes. Try it: sort a column, type in the search box, tick rows.
<xo-view get="listPeople">
<xo-table columns="name,email:E-mail,role" sortable filters="name:Search by name" selectable page-size="5" empty="Nobody here">
<span slot="role" class="badge">{role}</span>
<button class="danger" xo-click="deletePerson" xo-confirm="Delete {name}?" xo-notice="Deleted">Delete</button>
<button slot="bulk" class="danger" xo-click="deletePerson" xo-selected>Delete ticked</button>
</xo-table>
</xo-view>import { configure } from '@xoong/data';
import '@xoong/data/view';
import '@xoong/ui';
import operations from '/.xoong/operations.json' with { type: 'json' };
configure({ api: operations, baseUrl: '/api' });{
"paths": {
"/api/people": {
"get": {
"operationId": "listPeople",
"parameters": [{ "name": "sort", "in": "query" }, { "name": "limit", "in": "query" }, { "name": "offset", "in": "query" }, { "name": "name", "in": "query" }],
"responses": { "200": { "description": "ok" } }
}
}
}
}There is no server behind this page: a function in the page plays the API (configure({ fetch })), and everything else, the typed operation, the cache, the loading and error states, is the real thing.
Ideas
Standards first
Custom elements in the Light DOM, the History API, native <dialog> and Popover, Intl, ElementInternals for form controls.
Your API is the contract
xoong sync reads OpenAPI and writes typed operations. Tables and forms are drawn from the schemas; validation comes from them too.
Plain CSS
Design tokens are custom properties in cascade layers. Your own CSS always wins, no utility classes, no CSS-in-JS.
Strict CSP ready
xoong build writes static output with no inline code and no import map. This site is built that way.
Accessible by default
Tabs, menu, tooltip, combobox and the toolbar follow the WAI-ARIA patterns, with keyboard support and tests in three browsers.
Made for AI and humans
A short llms.txt, an MCP server, and xoong check, which catches mistakes in markup and tells you the fix.
Where to go next
- Install xoong and start a project in a few commands.
- Read how it works, then the guides: data and tables, forms, controls, rich text and styling.
- Open the live demo, a small admin screen, or the full pages: an admin and a landing page.