How a generated screen lands as real layers
Ask Lindi Code for a screen and what reaches the canvas is frames with auto layout, real component instances and prototype links — editable like anything you drew. Here is how the generation is built so that is true.
Most AI design generators give you an image, or a block of code you paste somewhere and then rebuild. Neither is a design you can keep working on. We wanted a generated screen to behave exactly like a screen somebody drew: selectable, nested, bound to the same components and variables, undoable. That decision shaped the whole architecture.
Two layers, kept apart on purpose
The model never sees the editor. It produces a compact description of intent — screens, a layout hierarchy of columns, rows and text, component calls by name with variants and property overrides, and interactions keyed to stable screen names. No node ids, no coordinates, nothing about undo. Every response is stripped of empty values, validated against a strict schema that rejects unknown keys, and then checked against the registry: does that component exist, does that variant, does that property, does that destination screen.
{ "screens": [{ "key": "menu", "purpose": "Browse tonight’s dishes and add to an order", "layout": { "kind": "column", "children": [ { "component": "dish-cell", "variant": { "size": "default" }, "props": { "name": "Margherita", "price": "14.00" } }, { "component": "dish-cell", "props": { "name": "Diavola" } } ]}, "interactions": [{ "on": "add", "go": "cart" }] }]}The second layer runs in the editor and turns validated intent into complete native nodes — using the same factories manual creation uses, committed through the same mutation path. That is why undo, autosave, realtime collaboration, selection and the inspector all work on a generated screen without a special case: as far as the document is concerned, nobody generated anything.
The part people asked for and did not get
Screens are generated from a plan, not from the conversation, and for a while that lost things. If you had said “a destination search” for a screen, a one-line purpose was not enough to carry it, and the screen arrived as if you had never asked. So the plan now captures every element you named for a screen, verbatim. Each one is bound into that screen’s generation as mandatory content, and the section that satisfies it has to be named after it — which costs the design nothing and makes compliance checkable.
After generation, a matcher compares your words to the screen’s own words — layer names, copy, component keys — and anything unmatched becomes an error the existing repair pass fixes by name. If it is still missing after that, the screen ships with a warning that names the gap, rather than failing. A missed requirement can cost a round trip; it never costs you the screen.
- Intent is validated three times before it is drawn
- Nodes are built by the same code that builds a hand-drawn frame
- Prototype links resolve by screen name, so renaming never breaks them
- Your named requirements are checked for, and repaired if missed
Reading about it is one thing. Lindi is open by request, and free for early users.
Request access