Skip to content
Cathy Guarino

Lumonus: Building an agentic design system

As we increasingly use AI agents to build interfaces, development gets dramatically faster - but design issues start appearing just as quickly. Familiar patterns begin to drift, components fragment, and design personality gets lost.

I explored how a design system could improve AI-generated interfaces, without sacrificing the speed that makes this way of working so powerful.

Lumonus · Technical Lead · 2026

A modular agent workflow moving through a design-system grid, with a signal pulsing along the connections.

Overview

This began as an experiment in AI-driven development. Our engineering team was moving to an entirely AI-driven way of working, and everyone was excited about how fast we could build.

I saw that whilst we were building features remarkably quickly, design quality in the product was quickly dropping. Components were duplicated, established patterns went unused and similar interactions began to diverge across the product.

I designed and built a new design system architecture for AI-driven development, making the system easier for agents to understand, and creating mechanisms for new UI patterns to be captured and reused.

A design system built for AI

For an agentic design system to be successful, it needed to raise the quality and consistency of the interface, without compromising the speed or autonomy that make agentic development so powerful. It had to fit naturally into the existing development practice without adding new review steps or bottlenecks. I was also interested in creating space for human craft: giving designers opportunities to bring creativity and domain knowledge to the product without slowing developers down.

The solution described here is the result of extensive experimentation and trial and error. The final working system incorporates three main ideas - hover to explore:

  1. Make the design system legible to AI. Give agents a reliable way to read the design system, use it correctly and ship, without getting in the way.More details
  2. Separate experimentation from stability. Let agents create and ship new patterns quickly without requiring every generated component to become part of the shared system.More details
  3. Let the system evolve from the product. Identify successful patterns as they emerge and feed them back into the stable design system.More details

Making the design system legible to AI

The first issue was surprisingly basic: agents weren't reliably using existing components.

The agents had access to the entire codebase, and we already had a library of components that covered most use cases. However, agents repeatedly created new near-identical components from scratch. The problem was that they had no reliable way to discover components or understand when to use them.

With a traditional design system, developers build up this knowledge over time. They browse documentation, recognise familiar patterns and understand the intent behind components. AI doesn't have that accumulated context; it has to infer it from the code every time.

I built a machine-readable registry that described every component, the problem it solved, its available variants and when it should - and shouldn't - be used. Agents directly reference this registry to identify appropriate existing components; the design system became a data structure AI could query, rather than source code it had to interpret.

Designing the registry content was iterative. Small changes to the information it exposed had a noticeable effect on the quality of the results. One of the biggest improvements came from documenting when not to use a component, which helped agents distinguish between similar options and choose the most appropriate.

{
      "name": "Accordion",
      "importPath": "/design-system",
      "description": "Vertical stack of expandable sections — each header toggles a collapsible content region.",
      "whenToUse": "Grouped expandable content where one (or several) sections need to be visible at a time — FAQs, settings groups, clinical detail panels with hidden subsections. Use type='single' with collapsible for one-open-at-a-time; type='multiple' when users need to compare multiple open sections.",
      "whenNotToUse": "Tab strips that switch between mutually exclusive views (use Tabs). A single standalone disclosure toggle (use a details/summary or a future Collapsible primitive). Nested navigation (use Sidebar sections). Anything where the trigger needs to navigate to a new route rather than reveal inline content.",
      "props": [
        { "name": "type", "type": "'single' | 'multiple'", "required": true, "description": "Selection mode. 'single' allows at most one open item at a time; 'multiple' allows any number open simultaneously." },
        { "name": "collapsible", "type": "boolean", "default": "false", "required": false, "description": "Accordion (type='single') only. When true, clicking the open item's trigger closes it. When false, one item is always open." },
        { "name": "defaultValue", "type": "string | string[]", "required": false, "description": "Uncontrolled default open item(s) at mount. String for type='single'; string[] for type='multiple'." },
        { "name": "value", "type": "string | string[]", "required": false, "description": "Controlled open item(s). Pair with onValueChange." },
        { "name": "onValueChange", "type": "(value: string | string[]) => void", "required": false, "description": "Called with the new open value(s) when an item is toggled." },
        { "name": "disabled", "type": "boolean", "required": false, "description": "AccordionItem: disables the item's trigger (pointer-events-none, dimmed). Applied per-item, not on the root." }
      ],
      "variants": [...],
      "status": "stable",
      "composes": [...]
    },

Above: An example of an entry the agents read when selecting a component to use.

Separating experimentation from stability

The product was evolving quickly, and new components and patterns appeared almost every day. Requiring every new component to be reviewed before it could be used and shipped would have slowed development dramatically. But, allowing every new generated component into the design system would quickly fill it with one-off solutions and duplicate patterns.

The traditional design workflow - design, review, implement, review again - doesn't fit an environment where implementation happens in minutes.

I separated the design system into two layers:

  1. Stable components form the formal design system. They're reviewed, tested and intended for repeated use across the product.
  2. Experimental components are everything else. Developers and AI agents can create new components whenever needed and ship immediately without review.

This separation meant that development could continue at full speed, while the stable design system remains controlled, high quality, and scalable.

Both layers are governed by engineering standards, but with different expectations. Experimental components are held to practical standards for structure, accessibility and styling so they remain maintainable and consistent. Stable components have a higher bar; they must be generic, reusable and suitable for use across the product.

The goal wasn't to stop agents creating new components. It was to make sure the best ones became shared, repeatable patterns.

Letting the design system evolve

Without close oversight, design systems can fall behind while new patterns accumulate outside them. I wanted this design system to evolve continuously, without manual intervention.

A sweeper agent regularly scans the codebase for repeated components, near-duplicate implementations and recurring interaction patterns, surfacing them as candidates for the stable design system. Straightforward cases are handled automatically: an extender agent extracts the component, generates documentation and tests, updates the machine-readable registry and migrates existing usages.

More nuanced patterns became opportunities for design. Rather than reviewing every generated interface before it ships, designers can focus on patterns that have emerged through real product work - refining interactions, improving accessibility and bringing greater craft to the system.

The design system evolves from recurring patterns rather than upfront prediction. Agents use it to build the product, new patterns emerge through feature work, and the strongest feed back into the system. The result is a continuous loop that keeps the design system aligned with the product.

Outcome

The result was a more consistent, considered interface that continued to improve as the product evolved. The design system could evolve autonomously alongside feature delivery, without slowing it down, while creating more space for designers to bring craft and judgement to the patterns shaping the product.

That doesn't mean the problem is solved. The tooling is evolving too quickly for that, and I'm still exploring ways to improve the system. But it has changed how I think about design systems in an AI-driven environment. As more implementation shifts to agents, design systems can no longer be passive collections of components and documentation: they need to encode design intent in a way that allows thousands of automated decisions to become a coherent, high-quality product.