Phase 1 | Yui Lines v0

Playground

The agent never writes UI code. It sends one short line per component, and the app renders a prebuilt preset. Pick a screen, edit the line, or press Stream to watch it render as the model types. Grammar: Yui Lines spec.

Stream speed
Agent line (applied on top, no re-render):
Wire log (what the agent receives back)
Tap something on the phone.
A
Arnold
screen 1
Tabata
Round 1 of 8
0:40
WORK

Token benchmark: YL vs JSON

The same 10 screens as the dropdown above, counted with real tokenizers. The JSON is generated from the parsed YL, so both sides say exactly the same thing with the same defaults. min is minified JSON (the cheapest JSON can get), pretty is how models usually emit it, and tree is the usual generative-UI component tree.

Screen (o200k_base)YLJSON minJSON prettyJSON treemin / YLtree / YL
1. Tabata timer92543752.8x8.3x
2. Log a set243654931.5x3.9x
3. Pick a split162950821.8x5.1x
4. Gear check253964961.6x3.8x
5. Onboarding47861511971.8x4.2x
6. Today's workout50691081581.4x3.2x
7. Meal photo log82241802.8x10.0x
8. Macros so far57821632021.4x3.5x
9. Book a client call46651111571.4x3.4x
10. Leg day card + voice log56771191651.4x2.9x
Total33853090413051.6x3.9x
Tokenizer (totals)YLJSON minJSON prettyJSON treepretty / YLtree / YL
o200k_base via js-tiktoken33853090413052.7x3.9x
cl100k_base via js-tiktoken34552991213132.6x3.8x
@anthropic-ai/tokenizer34152288212842.6x3.8x

Read it straight: against the leanest possible JSON, YL saves about a third of the tokens. Against JSON as models actually write it, 2.6x to 3.9x. The win is biggest on short control screens (a timer, a camera) and smallest where the screen is mostly the user's own text, which costs the same in any format. The Claude column uses Anthropic's legacy published tokenizer, since current Claude tokenizers are not available offline. Generated 2026-09-23 by bench/bench.mjs.

Screen 1 as a JSON component tree (75 tokens) vs YL (9 tokens)

{
  "screens": [
    {
      "id": "1",
      "children": [
        {
          "type": "Timer",
          "props": {
            "work": 40,
            "rest": 20,
            "rounds": 8,
            "label": "Tabata"
          }
        }
      ]
    }
  ]
}
timer 40/20x8 Tabata