Skip to content

Status and limits ​

SayShape is an early prototype, version 0.1. This page separates what's built from what's planned. If something isn't listed as built, assume it isn't.

Built ​

  • The engine: parser, expressions, actions, layout, painting, hit testing, keyboard focus (including parts of elements), popups and the inspector.
  • 60 elements (reference): layout, content (including callout, tiles for cards, seats and keys, scrolling regions, dialogs and menus), data (stat with a change and sparkline, rating, details for one record, charts: multi-series bar, horizontal bar and line, stacked bars, area, pie, donut, funnel, waterfall, bullet, heatmap, scatter, treemap and sankey, meters as a ring or a gauge, tables with sorting and selection, schedules of shifts, bookings and Gantt-style plans, boards of cards by stage, trees (lists that open and close, and org charts), flows laid out automatically, the world map), input (buttons, checks, switches, radios, select, date picker, stepper, slider, text input), navigation (screens, tabs, breadcrumb, pagination) and feedback (progress, skeleton, empty).
  • State with lists and records, host data, each with keys and nesting, bind= and actions on paths, add, remove and clear, if blocks, derive lines, list and formatting functions, screens with go: and back, notify: messages, and images from allowed hosts.
  • The model guide (full and compact, with profiles), sayshape/model (streaming, cleaning, checking, one repair, bounded refinement), an evaluation script, and sayshape/testing.
  • Accessibility: a hidden mirror of the canvas for screen readers, keyboard focus that follows it, chart and map text alternatives, contrast, high-contrast mode and reduced motion (Accessibility).
  • Unit, contract, streaming, fuzz and visual tests, benchmarks, a component scaffold and CI.

Not built yet ​

  • Data sources and host commands. Your app fetches data and sets state; a spec can't declare where data comes from.
  • Forms beyond the basics. Fields take several lines (lines=) and say what's wrong once left (required=, kind=email, kind=number, error=), but nothing checks every field at once on submit; hold a submit button back with disabled={…}.
  • Overlays beyond dialogs, menus and tips. No toasts or sheets. (tip= on any element shows a short tooltip.) The popup layer serves a component's own popup (a select's list, a menu's actions), and dialog is the one overlay, one open at a time. (scroll gives a scrolling area inside a screen, up and down only, without virtualization.)
  • Typing to search in a select, and option groups. (A select picks several with multiple=true.)
  • Larger tables: more than 200 rows, vertical scrolling, sticky headers, editable cells, multi-row selection. (Wide tables already scroll sideways.)
  • More charts: series from different lists and time axes. Only kind=scatter has a numeric x-axis.
  • Dates and times beyond the basics: time zones, recurring events, blocks past midnight, other locales. (A date picker picks a range with range=true; schedule lays out times and dates.)
  • Packaging: an npm release and a production model server.

Built-in limits ​

LimitValue
Nesting depth100 levels; deeper lines are an error and skipped
Derived values per spec200
Items per each500
Repeated elements per screen10,000
Data literals20 levels deep, 10,000 values
Data from the app (state.set)20 levels deep, 1,000,000 values (each row and field counts)
select options200, eight shown at once
table200 rows and 64 columns; a message instead of more. Columns that don't fit scroll sideways
chart200 items, 6 series, 6 pie or donut slices (the rest summed into Other)

Numbers, money and dates are formatted in US English. Weeks start on Sunday.

Measured results ​

The landing page's two numbers come from one limited, recorded comparison, and nothing more general:

  • What: 7 requests (a signups chart with a week/month toggle, a spending tracker, a sign-up form, a to-do list, a budget tracker, a product table with a search box and a mortgage calculator), each answered by Claude Sonnet 5.5 in SayShape, in HTML and in A2UI at the same moment, in November 2026. The recordings are on the Compare page, which replays each answer at the speed it arrived.
  • Output tokens: estimated as characters ÷ 4, because they come from the recorded text. Medians: SayShape 171, A2UI 628, HTML 1,299, so HTML took 7.6 times as many.
  • Time: from the request until the model's output was complete. Medians: SayShape 2.4 s, HTML 13.2 s, A2UI 17.2 s. From the unrounded medians (2.43 s and 13.18 s), HTML took 5.4 times as long.
  • What it doesn't say: it measures the model's output only, not how long a screen takes to draw or how fast your app is. It's one model and seven tasks; other models and requests will give other numbers. Record your own with scripts/record.ts, or score whole answers with npm run compare.

Model quality varies by model too; measure yours with npm run eval. The engine's own timings are shown in the playground for the spec you're looking at.

Roadmap ​

The phase plan is in docs/PLAN.md in the repository: data sources next, then the model server and an app built on top.

SayShape v0.1 is an early prototype under the MIT License. Status · GitHub