---
title: Benchmarks
description: Token efficiency and latency comparison of OpenUI Lang vs YAML, Vercel JSON-Render, and Thesys C1 JSON.
---

OpenUI Lang is designed to be token-efficient and streaming-first. This page presents a reproducible benchmark comparing it against three structured alternatives across seven real-world UI scenarios: YAML, Vercel JSON-Render, and Thesys C1 JSON.

## Formats Compared

| Format                 | Description                                                                |
| ---------------------- | -------------------------------------------------------------------------- |
| **OpenUI Lang**        | Line-oriented DSL streamed directly by the LLM                             |
| **YAML**               | YAML `root` / `elements` spec payload                                      |
| **Vercel JSON-Render** | JSONL stream of [JSON Patch (RFC 6902)](https://jsonpatch.com/) operations |
| **Thesys C1 JSON**     | Normalized component tree JSON (`component` + `props`)                     |

### Same output, different representations

All four formats encode exactly the same UI. Here is the same simple table in each:

**OpenUI Lang** (154 tokens)

```text
root = Stack([title, tbl])
title = TextContent("Employees (Sample)", "large-heavy")
tbl = Table([Col("Name", names), Col("Department", departments), Col("Salary", salaries, "number"), Col("YoY change (%)", changes, "number")])
names = ["Ava Patel", "Marcus Lee", "Sofia Ramirez", "Ethan Brooks", "Nina Chen"]
departments = ["Engineering", "Sales", "Marketing", "Finance", "HR"]
salaries = [132000, 98000, 105000, 118500, 89000]
changes = [6.5, 4.2, 3.1, 5.0, 2.4]
```

**YAML** (316 tokens)

```yaml
root: stack-1
elements:
  textcontent-2:
    type: TextContent
    props:
      text: Employees (Sample)
      size: large-heavy
  table-3:
    type: Table
    props:
      rows:
        - [...]
    children:
      - col-4
      - col-5
      - col-6
      - col-7
  stack-1:
    type: Stack
    props: {}
    children:
      - textcontent-2
      - table-3
```

**Vercel JSON-Render** (340 tokens)

```jsonl
{"op":"add","path":"/root","value":"stack-1"}
{"op":"add","path":"/elements/textcontent-2","value":{"type":"TextContent","props":{"text":"Employees (Sample)","size":"large-heavy"},"children":[]}}
{"op":"add","path":"/elements/col-4","value":{"type":"Col","props":{"label":"Name","type":"string"},"children":[]}}
{"op":"add","path":"/elements/col-5","value":{"type":"Col","props":{"label":"Department","type":"string"},"children":[]}}
{"op":"add","path":"/elements/col-6","value":{"type":"Col","props":{"label":"Salary","type":"number"},"children":[]}}
{"op":"add","path":"/elements/col-7","value":{"type":"Col","props":{"label":"YoY change (%)","type":"number"},"children":[]}}
{"op":"add","path":"/elements/table-3","value":{"type":"Table","props":{"rows":[...]},"children":["col-4","col-5","col-6","col-7"]}}
{"op":"add","path":"/elements/stack-1","value":{"type":"Stack","props":{},"children":["textcontent-2","table-3"]}}
```

**Thesys C1 JSON** (357 tokens)

```json
{
  "component": {
    "component": "Stack",
    "props": {
      "children": [
        { "component": "TextContent", "props": { "text": "Employees (Sample)", "size": "large-heavy" } },
        { "component": "Table", "props": { "columns": [...], "rows": [...] } }
      ]
    }
  },
  "error": null
}
```

---

## Token Count Results

Generated by GPT-5.2 at temperature 0. Token counts measured with `tiktoken` using the `gpt-5` model encoder.

| Scenario           |      YAML | Vercel JSON-Render | Thesys C1 JSON | OpenUI Lang |    vs YAML |  vs Vercel |      vs C1 |
| ------------------ | --------: | -----------------: | -------------: | ----------: | ---------: | ---------: | ---------: |
| simple-table       |       316 |                340 |            357 |         148 |     -53.2% |     -56.5% |     -58.5% |
| chart-with-data    |       464 |                520 |            516 |         231 |     -50.2% |     -55.6% |     -55.2% |
| contact-form       |       762 |                893 |            849 |         294 |     -61.4% |     -67.1% |     -65.4% |
| dashboard          |     2,128 |              2,247 |          2,261 |       1,226 |     -42.4% |     -45.4% |     -45.8% |
| pricing-page       |     2,230 |              2,487 |          2,379 |       1,195 |     -46.4% |     -52.0% |     -49.8% |
| settings-panel     |     1,077 |              1,244 |          1,205 |         540 |     -49.9% |     -56.6% |     -55.2% |
| e-commerce-product |     2,145 |              2,449 |          2,381 |       1,166 |     -45.6% |     -52.4% |     -51.0% |
| **TOTAL**          | **9,122** |         **10,180** |      **9,948** |   **4,800** | **-47.4%** | **-52.8%** | **-51.7%** |

OpenUI Lang uses up to **61.4% fewer tokens** than YAML, **67.1% fewer** than Vercel JSON-Render, and **65.4% fewer** than Thesys C1 JSON.

---

## Estimated Latency

Latency scales linearly with output token count at a given generation speed. At **60 tokens/second** (typical for hosted frontier models):

| Scenario           |   YAML | Vercel JSON-Render | Thesys C1 JSON | OpenUI Lang |  Speedup vs YAML | Speedup vs Vercel |
| ------------------ | -----: | -----------------: | -------------: | ----------: | ---------------: | ----------------: |
| simple-table       |  5.27s |              5.67s |          5.95s |       2.47s | **2.14x faster** |  **2.30x faster** |
| chart-with-data    |  7.73s |              8.67s |          8.60s |       3.85s | **2.01x faster** |  **2.25x faster** |
| contact-form       | 12.70s |             14.88s |         14.15s |       4.90s | **2.59x faster** |  **3.04x faster** |
| dashboard          | 35.47s |             37.45s |         37.68s |      20.43s | **1.74x faster** |  **1.83x faster** |
| pricing-page       | 37.17s |             41.45s |         39.65s |      19.92s | **1.87x faster** |  **2.08x faster** |
| settings-panel     | 17.95s |             20.73s |         20.08s |       9.00s | **1.99x faster** |  **2.30x faster** |
| e-commerce-product | 35.75s |             40.82s |         39.68s |      19.43s | **1.84x faster** |  **2.10x faster** |

The latency advantage compounds with UI complexity. A contact form renders **up to 3.0× faster**, and even complex dashboards and pricing pages — the kinds of UIs where Generative UI delivers the most value — render **2–3× faster** with OpenUI Lang.

---

## Methodology

<div className="grid md:grid-cols-2 gap-6 my-6">
  <div className="p-5 border border-slate-200 dark:border-slate-800 rounded-xl bg-slate-50 dark:bg-slate-900/40">
    <div className="font-semibold mb-2">Model</div>
    <p className="text-sm text-slate-600 dark:text-slate-400">
      GPT-5.2, temperature 0. Same system prompt and user prompt for every scenario. Each format is
      derived from the same LLM output, not independently generated.
    </p>
  </div>
  <div className="p-5 border border-slate-200 dark:border-slate-800 rounded-xl bg-slate-50 dark:bg-slate-900/40">
    <div className="font-semibold mb-2">Conversion</div>
    <p className="text-sm text-slate-600 dark:text-slate-400">
      The LLM generates OpenUI Lang. Thesys C1 JSON is a normalized AST projection (`component` +
      `props`) that drops parser metadata (`type`, `typeName`, `partial`, `__typename`). The YAML
      payload and Vercel JSON-Render output are two serializations of the same json-render spec
      projection (`root`, `elements`, optional `state`): JSONL emits RFC 6902 patches, while YAML is
      serialized with <code>yaml.stringify(..., &#123; indent: 2 &#125;)</code>.
    </p>
  </div>
  <div className="p-5 border border-slate-200 dark:border-slate-800 rounded-xl bg-slate-50 dark:bg-slate-900/40">
    <div className="font-semibold mb-2">Token Counting</div>
    <p className="text-sm text-slate-600 dark:text-slate-400">
      All formats measured with <code>tiktoken</code> using the <code>gpt-5</code> model encoder —
      the same tokenizer family as GPT-5.2. Whitespace and formatting is included as-is in the
      count. For YAML, the benchmark counts the document payload only and excludes the outer
      <code>yaml-spec</code> fence.
    </p>
  </div>
  <div className="p-5 border border-slate-200 dark:border-slate-800 rounded-xl bg-slate-50 dark:bg-slate-900/40">
    <div className="font-semibold mb-2">Latency Model</div>
    <p className="text-sm text-slate-600 dark:text-slate-400">
      Assumes constant throughput (60 tok/s). Real latency also depends on TTFT and network.
      Streaming advantage is most visible for the <em>last element to render</em>, not just overall
      time.
    </p>
  </div>
</div>

### Why is JSON-Render heavier than expected?

Vercel JSON-Render encodes each element as a separate `{"op":"add","path":"/elements/id","value":{...}}` line. The `op`, `path`, `value`, `type`, `props`, and `children` keys repeat for every node. For deeply nested UIs (dashboards, pricing pages), the structural repetition accumulates significantly — up to **3.0× the tokens** of OpenUI Lang across our scenarios.

---

## Reproducing the Benchmark

The benchmark scripts live in `benchmarks/`. To regenerate:

```bash
# 1. Generate samples (calls OpenAI — requires OPENAI_API_KEY in your shell)
cd benchmarks
pnpm generate

# 2. Run the token/latency report (offline, no API calls)
pnpm bench
```

Source files:

- `generate-samples.ts` — calls OpenAI, converts output to all four formats, saves to `samples/`
- `run-benchmark.ts` — reads saved samples, counts tokens, prints the tables
- `thesys-c1-converter.ts` — AST → normalized Thesys C1 JSON converter
- `vercel-spec-converter.ts` — AST → shared json-render spec projection (`root` / `elements`)
- `vercel-jsonl-converter.ts` — shared spec → RFC 6902 JSONL converter
- `yaml-converter.ts` — shared spec → YAML document converter
- `schema.json` — full JSON Schema for the default component library (auto-generated by `library.toJSONSchema()`)
- `system-prompt.txt` — system prompt for the default component library (auto-generated by `library.prompt()`)
