---
title: "How it works"
description: "What happens between a model writing a line of GistUI Lang and a component appearing on screen."
---

> Documentation Index
> Fetch the complete documentation index at: https://gistui.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# How it works

GistUI has four moving parts: a **language** the model writes, a **catalog** that says which components exist, a **processor** that turns text into a tree, and a **renderer** that draws it.

## 1. The model writes statements

A GistUI program is a list of short statements, one per line: `id = value`. The first is `root`. Later lines fill in the parts it refers to.

```gistui
root = Page(head, kpis)
head = Header("Q3 revenue", "All regions")
kpis = Stats(kpiData)
kpiData = |Label|Value|Delta
|Revenue|$1.2M|+8%
|Customers|3,410|+2.1%
```

Three choices in the language make streaming work:

- **Layout first, data last.** `root` arrives in the first line, so the page has a shape before any data exists. Parts that are not defined yet show as placeholders.
- **Flat and line-based.** A line is complete when its newline arrives. Nothing has to be closed far away, unlike nested JSON.
- **Data written once.** A table is pipe rows, and one table can feed a chart, a table and a KPI row.

## 2. The catalog directs the parser

The catalog lists every component with its positional arguments, props, enum values and flags. The parser reads with the catalog in hand, so short forms are never ambiguous:

```gistui
card = Card(a, b, sunk, gap:lg)
```

`sunk` is an enum value of `Card`'s `v` prop, `gap:lg` is a named prop, and `a` and `b` are references. The parser decides this from the catalog and what it has already read, never from text that has not arrived yet.

The same catalog generates the system prompt, so the model is told exactly what the parser accepts.

## 3. The processor emits patches

The parser is incremental. Each chunk of text is scanned once; a completed statement is parsed once and frozen. The result is not a new tree per chunk but a stream of small **patches**: create this node, set that prop, append these rows.

| | Re-parse everything on each chunk | GistUI |
|---|---|---|
| Work per chunk | grows with the answer so far | only the new text |
| What re-renders | the whole tree | the nodes a patch touched |

In Chrome, rendering a streaming answer takes 2–6× less main-thread work than OpenUI on OpenUI's own sample screens. See [Benchmarks](/docs/reference/benchmarks/) for how these were measured.

## 4. The renderer draws only what changed

Every node has a stable id. Each rendered component subscribes to its own node, so a patch re-renders that component and nothing else. Patches are flushed once per animation frame.

While a part is still streaming, its interactive controls are locked (`lockUntil`), so a person cannot submit half a form.

## 5. At the end: autofix

Models make small, repeated mistakes: a prop that does not exist, a misspelled component, a reference nobody defined. Two layers deal with them.

- **While reading**, the format's recovery rules say exactly how each slip is read (single quotes, a missing bracket, `key=value`). Two implementations give the same tree for the same imperfect text.
- **When the stream ends**, `autofix` repairs what is still wrong: it removes unknown props, corrects close enum values, renames misspelled components, drops dangling references and places unused statements. It is plain code and takes a few milliseconds.

On the benchmark, autofix takes validity from 88% to 100% with gpt-oss-120b. See [Autofix and repair](/docs/guides/autofix/).

## 6. The runtime handles interaction

A program can hold state (`$tab = "a"`), read data through your tools (`@query`), and describe what a button does (`do:[…]`). The runtime evaluates these in the browser. It interprets expressions; it never compiles or evaluates code, so a strict Content-Security-Policy works.

Everything a person does reaches your app through one callback, `onAction`. See [Actions and forms](/docs/guides/actions-and-forms/).

## The packages

| Package | Role |
|---|---|
| `@gistui/core` | The language: lexer, parser, patches, validation, autofix, prompt generator. No dependencies. |
| `@gistui/catalog` | The 63 default component schemas and the system prompt built from them. |
| `@gistui/react`, `vue`, `svelte`, `solid`, `vanilla` | Renderers. Vue, Svelte and Solid are thin layers over `vanilla`. |
| `@gistui/styles` | One stylesheet for every renderer. |
| `@gistui/server` | Stream reading, validation and repair on the server. Optional. |
| `@gistui/chat` | A headless chat store, model adapters and React chat layouts. Optional. |

Full list: [Packages](/docs/reference/packages/).

Source: https://gistui.com/docs/get-started/how-it-works/index.mdx
