Components don't exist in isolation—they exist in relationships. A graph-based model that captures not just what components are, but how they're meant to work together.
flowchart TD
Card[Card]
Card --> Icon[Icon]
Card --> Text[Text]
Card --> Button[Button]
Icon -.->|valid pair| Button
Button -.->|invalid| Button2[Button] The Problem
Design systems document components as independent units. Button has props. Card has slots. Modal has variants. But the real knowledge— which components belong together, which combinations violate intent, which patterns work at scale—lives in tribal knowledge and code review comments.
AI agents generating UI lack this compositional understanding. They can read component APIs but not the invisible graph of relationships between them.
The Proposal
Explicit graphs of component relationships. Not just "Button exists" but "Button + Icon is valid, Button inside Button is invalid, Button in Card footer is the primary action pattern."
Nodes: Components with their constraints
Edges: Valid compositions with context
Weights: Preference scores for common patterns
When an agent proposes a component tree, the graph validates structure before rendering. Invalid compositions fail fast with explanations. Unusual-but-valid combinations get flagged for human review.
agent.propose({
root: "Card",
children: [
{ component: "Icon", props: { name: "warning" } },
{ component: "Text", props: { content: "Alert message" } },
{ component: "Button", props: { label: "Dismiss" } }
]
}) graph.validate({
check: "Card > Icon + Text + Button",
rules: [
{ rule: "card-allows-icon", result: "pass" },
{ rule: "card-allows-text", result: "pass" },
{ rule: "card-allows-button", result: "pass" },
{ rule: "icon-button-pairing", result: "pass" }
]
}) agent.propose({
root: "Button",
children: [{ component: "Button", props: { label: "Inner" } }]
})
graph.reject({
rule: "no-nested-interactive",
message: "Button cannot contain Button",
suggestion: "Use ButtonGroup for adjacent actions"
}) Agent proposes a Card with Icon, Text, and Button children
Graph validates all composition rules pass
Invalid nested composition rejected with alternative suggestion
Why Now
Agentic development doesn't just generate components—it generates compositions. The failure mode isn't "wrong button" but "wrong arrangement of correct buttons." Current linting catches syntax; intent graphs catch semantics.
GraphQL proved that explicit schemas beat implicit assumptions. The same principle applies: make the composition rules machine-readable, and machines can follow them.
Prior Art
Figma's auto-layout constraints. SwiftUI's view builder restrictions. HTML's content model (block vs inline). BEM methodology's implicit hierarchy. The concept exists in fragments—it needs consolidation into a formal, queryable structure.
flowchart TD
Propose[Agent proposes tree] --> Validate[Graph validates]
Validate --> Valid{Valid?}
Valid -->|yes| Render[Render]
Valid -->|no| Error[Error + alternatives]