Your Props Are a Prompt Surface: Component API Design in the AI Era

Nov 2026

5 min read · Design systems · Craft

Composition over configuration, and why I think the best component APIs make invalid states impossible.

Hand-drawn mindmap of component API design

Why this is on my mind

As a designer who works closely with code, I've started treating a component's props as the product's grammar. That grammar now has two readers: the developer and the model. A confusing API used to cost a developer an afternoon. Now it also causes a model to confidently generate a combination that was never meant to exist.

Booleansdouble the stateshidden conditionalsBorrowreuse known vocabularyDefaultsstrong and sensibleTwo readersdevelopermodelCompositioncompound partsexplicit variantsImpossiblemake them unwritableComponent API
Why props are a grammar with two readers.

What's true right now

The consensus is to prefer composition. A well-known guide to component APIs for design systems says to treat each component as an API, name boolean props as adjectives (like disabled or compact), avoid is and has prefixes, and prefer composition over piling on toggle props. It explains the usual failure: a new requirement arrives, someone adds a boolean to switch behavior, and past a certain complexity the component should have been split.

The problem has a name now. Agent skills for React composition describe boolean prop proliferation in blunt terms: each extra boolean roughly doubles the possible states and creates conditional logic nobody wants to maintain. The suggested replacements are compound components, lifted state, and explicit variants. The fact that these now ship as installable skills for coding agents is telling: the audience for good API taste includes machines.

Foundations matter. Emil Kowalski built his drawer component Vaul on Radix's Dialog primitive so accessibility and focus management come built in, and kept the API close to Radix's so it feels familiar. Good APIs borrow vocabulary instead of inventing it.

Generated UI raises the bar on defaults. A developer who has shipped generative UI in production notes that a table rendered by an agent exists because the agent already filtered the data, so it needs strong defaults and sensible truncation rather than assuming the user will fix it.

A worked example of a boolean pile-up

Illustrative: my own sketch, not a sourced fact.

How it usually starts. A button begins with one prop. Then a loading state arrives and someone adds a boolean. Then a destructive style, then a ghost style, each reasonable alone. Each addition roughly doubles the possible states, as the composition guidance describes, and nobody ever decided that loading and ghost and destructive together should be allowed.

What the structural version looks like. Replace the booleans with a short, named set of variants, and treat loading as a state of the parts, not a switch on the whole. Now the question a model faces is which variant fits, a finite choice, not which of many flags to combine. The impossible combinations are not discouraged. They simply cannot be written.

My hypothesis

This section is my opinion, not a sourced fact.

The best component API in the AI era is the one where an invalid combination cannot be expressed at all.

When only people used components, invalid combinations were caught by code review and common sense. A model has neither. If <Button loading disabled destructive ghost> is a legal call, a model will eventually make it. The defense is structural: fewer props, finite named variants, and composition where the parts only fit together the right way.

That means the API review I want is not "is this flexible?" but "what is the worst thing a confident stranger could build with this?" Flexibility is a cost I only pay when it earns its keep.

What I would do first on a real product

My opinion, based on the tradeoffs above.

Pick the component that hurts. I would not start with a full API audit. I would pick the one component that engineers complain about most and read its props aloud as a sentence. Wherever the sentence stops making sense, there is probably a combination that should not exist, and that is where I would begin.

Ask for the stranger's worst case. For each prop, I would ask what the worst thing a confident stranger could build with it is. If the answer is uncomfortable, the prop either needs to go, be narrowed to named choices, or move into a part that only fits where it should. Flexibility has to justify itself against that answer.

How I'd test it

Take one heavily used component. Count its legal prop combinations versus the number that make visual or product sense. Ask a model to generate 50 usages. Measure how many land in the nonsense set, then refactor to explicit variants and measure again.

What would change my mind

If models get consistently good at reading prop documentation and refusing nonsense combinations, I could loosen the structure. I wouldn't bet my design system on that yet.

What this costs

My opinion, based on the tradeoffs above.

Rigid APIs push work onto the system team. Every legitimate edge case that the variants do not cover becomes a request, and someone has to say yes or no. That friction is real. I think it is the right place for the friction to live, because the alternative is that the friction lands on users as broken screens.

Some flexibility is worth keeping. Composition is not a ban on freedom, and a heavily constrained component that cannot serve real needs will just be bypassed with custom code. The goal is that the flexible parts are the safe ones. I do not have a clean rule for where that line sits, and I suspect it differs by component.

References

  1. Imply, An Opinionated Guide to Component APIs
  2. Open Skill Index, react-composition skill
  3. Emil Kowalski, Building a drawer component
  4. Alex Cloudstar, Generative UI in 2026: What Actually Works for Developers