GenUI
Safety, accessibility, and styling
What a model's output can and cannot reach, how accessible names are enforced, and the hooks that style the headless output.
Model output is untrusted
Nothing a model writes reaches the DOM without passing through a schema and a component that renders it on purpose.
- The validator drops every prop a schema does not declare, so
dangerouslySetInnerHTML,on*handlers,style,srcDoc,className,id, andrefcannot reach the DOM. Component names are looked up in the catalog only, never through prototypes. - Links accept
http(s):,mailto:,tel:, relative, and#fragmentURLs; images accepthttp(s)and relative URLs.javascript:,data:,blob:,file:, protocol-relative URLs, and URLs hiding a scheme behind whitespace are not linked or loaded. - Absolute links get
rel="noopener noreferrer", and images load lazily without a referrer. - Text is text: Markdown and HTML are shown literally, including text computed from what the person typed.
- Expressions run in a whitelisted evaluator with size limits and cannot reach globals, prototypes, or functions outside the list.
- Buttons and submits are disabled while a response streams, so nothing acts on a half-written interface.
Limits
A response cannot lock the page: past these limits the rest is left out.
| Limit | Value |
|---|---|
Components per response | 1000 |
Component nesting | 40 levels |
Items in a list or data prop | 500 |
Table size | 24 columns and 800 cells |
Response text | 2 MB, nested at most 100 levels deep |
Expression | 500 characters and 200 nodes |
Reported errors | 50 |
Accessible by schema
A model is a poor judge of accessibility, so the schemas require the accessible name of everything that needs one. A component without it is not drawn, and the error tells the model what to add.
- Inputs require a label, buttons and links visible text, charts and cards a
title, tables acaption, and imagesalttext. There are no icon-only components. - Charts include a data table, and fields support help text through
aria-describedby. - Heading levels follow card nesting.
- Warnings and errors are announced at once; other messages are polite.
- The conformance suite runs axe over every answer at every stage of its stream, including open selects and calendars.
Style the output
comp0 ships no CSS. Every part carries a data-slot, and layout components carry token attributes that are absent when the model did not choose a value. The comp0 parts inside keep their own state attributes, such as data-checked, data-selected, data-open, and data-focus-visible, so one stylesheet themes everything a model can compose.
[data-slot="stack"] {
display: flex;
flex-direction: column;
gap: 1rem;
}
[data-slot="stack"][data-direction="row"] {
flex-direction: row;
}
[data-slot="grid"][data-columns="3"] {
display: grid;
grid-template-columns: repeat(3, minmax(0, 1fr));
}
[data-slot="card"][data-tone="accent"] {
border-color: teal;
}| Attribute | On | Values |
|---|---|---|
data-direction | Stack | column, row |
data-gap | Stack, Grid | xs, sm, md, lg, xl |
data-align | Stack | start, center, end, stretch |
data-wrap | Stack | Present when children wrap. |
data-columns | Grid | 1 to 6 |
data-tone | Card | default, muted, accent |
data-tone | Text | default, muted, success, warning, danger |
data-size | Text | sm, md, lg |
data-variant | Button | primary, secondary, danger |
data-tone | Alert | info, success, warning, danger |
data-numeric | Table cells | Present on cells that hold numbers. |