Components with honest APIs
Props speak the domain; variants are unions; composition beats configuration.
Use this when
isPrimary + isSecondary + isDanger on one component
A 'flexible' component with 30 props
Renaming a prop with no migration note
The quality gate
- Props read as the domain ('dueDate'), not the implementation ('leftPadding')
- Variants are unions ('variant="danger"'), never boolean soup ('isRed isBig isOutline')
- Composition over configuration: children > render props > a 12th boolean flag
- One component, one job — the second job becomes a second component
- Changing a prop's meaning ships with a migration note, not a silent break
Prove it: Write the component's job in one sentence and show a usage example — both must be obvious.
Install or copy
Save the download as component-api-design/SKILL.md in your agent's supported skills directory, or copy the complete package below. Load it only when its description matches the work.
---
name: component-api-design
description: "Applies “Components with honest APIs” as a repeatable product-quality gate. Use during frontend work when props speak the domain; variants are unions; composition beats configuration."
---
# Components with honest APIs
Apply this skill during **Frontend** work. It supports Next.js / React, Mobile, Any stack.
Props speak the domain; variants are unions; composition beats configuration.
## Instructions
Design component APIs the way you design REST APIs — for the caller, not the implementation. Props name domain concepts, not CSS ('status', not 'color'). Model variants as a single union prop; three booleans that only make sense in certain combinations are a state machine hiding in a trench coat. Prefer composition: accept children before adding configuration flags, and split the component when it grows a second job. Keep the required-prop count low — sensible defaults are part of the API. When a prop must change meaning, treat it as a breaking change: rename it and leave a migration note. If you can't write the component's job in one sentence, the API isn't done.
## Detect the problem
- isPrimary + isSecondary + isDanger on one component
- A 'flexible' component with 30 props
- Renaming a prop with no migration note
## Hold the gate
Do not declare this phase complete until every item passes:
- [ ] Props read as the domain ('dueDate'), not the implementation ('leftPadding')
- [ ] Variants are unions ('variant="danger"'), never boolean soup ('isRed isBig isOutline')
- [ ] Composition over configuration: children > render props > a 12th boolean flag
- [ ] One component, one job — the second job becomes a second component
- [ ] Changing a prop's meaning ships with a migration note, not a silent break
## Verify the result
Write the component's job in one sentence and show a usage example — both must be obvious.
More frontend skills
Hand-made over generated
Tokens, motion discipline, and the 100ms rule — the anti-slop frontend bar.
Performance is a budget, not a hope
Numbers written down, measured on the production build, enforced at the gate.
The accessibility floor
Keyboard, contrast, semantics, reduced motion — the floor nobody ships below.
Want this quality gate applied to a real product decision?
Start a First Loop