component-architecture — independently scanned and version-tracked by SaferSkills.
SaferSkills independently audited component-architecture (Agent Skill) and scored it 100/100 (green). The audit ran 55 deterministic rules across Security, Supply Chain, Maintenance, Transparency, and Community; it found 0 high-severity and 0 lower-severity findings. The full rule-by-rule trace and per-finding evidence are below. Free, methodology-open.
Findings & checks · 0 flagged
Every scanned point with the score it earned and what moved between them.
First recorded scan — no prior version to compare against.
The primary manifest — the file an agent reads to learn what this artifact does.
Component architecture is the discipline of structuring a library of UI components so their APIs outlive any single product, framework, or visual language. Every component is settled by four interlocking questions: layer — primitive, composite, or product-specific assembly, with dependencies flowing strictly downward; API surface — which props, slots, refs, callbacks, and render functions are open for extension versus closed for modification; state contract — controlled (the consumer owns the value), uncontrolled (the component owns it), or hybrid; and theming — the headless/styled split that lets behavior and visual treatment evolve independently. A component's API is the public contract between its author and every future consumer: once it ships, every prop, slot, event, and exposed ref becomes a thing future versions must keep supporting or break. The discipline replaces "a design system is a pile of components" with "components designed so their contracts survive multiple products and multiple visual languages."
The architectural discipline of structuring a library of UI components so they can be reused across products, themes, and teams. Covers the layering of primitives, composites, and product-specific assemblies; the composition-over-configuration principle and its trade-offs; the headless/styled split as the mechanism for behavior reuse across visual languages; controlled / uncontrolled / hybrid state contracts; the open-closed principle adapted to component evolution; polymorphism via as and asChild; extension mechanisms (props, children, slots, render props, compound components, ref forwarding); and the API-as-contract framing that makes component libraries survive multi-product, multi-year reuse.
The component's API is the contract between its author and every future consumer. Every prop, every slot, every event is a public surface that becomes a thing future versions must continue to support — or break consumers. Component architecture is the discipline of designing those contracts with the knowledge that you cannot predict every consumer and that the contract will be inhabited by integrations you didn't anticipate.
The discipline is upstream of any specific library, framework, or visual language. Layering, composition, the headless/styled split, the controlled/uncontrolled distinction, and the open-closed principle are properties of how components are structured — independent of which framework implements them and which design tokens style them. A team that internalizes these properties produces libraries that survive a decade of framework changes, brand refreshes, and product evolution. A team that does not produces libraries that work for the first product and require a rewrite for the second.
For agents working in component-heavy codebases, the discipline is the framework that lets the agent reason locally. Pick up a component, classify it by layer (primitive / composite / product-specific), inspect its API surface (props, slots, events), identify its state contract (controlled / uncontrolled / hybrid), and use it correctly without internalizing every idiosyncrasy. Without the framework, the agent pattern-matches against whatever the codebase already does — which means proliferating the codebase's existing architectural mistakes.
| Layer | What it is | Change rate | Reuse scope | Examples |
|---|---|---|---|---|
| Primitive | Smallest reusable unit; behavior only or behavior + minimal styling | Rare | All products | Button, Input, Checkbox, Popover, Dialog Root |
| Composite | Combines primitives into recurring patterns | Moderate | Most products | FormField (label + input + error), Card, DataTable |
| Product-specific assembly | Combines composites into unique product surfaces | Frequent | One product | CheckoutForm, SettingsPanel, DashboardWidget |
Dependencies flow downward (composites depend on primitives; assemblies depend on composites). Reversing the flow couples primitives to specific use cases and destroys reuse.
| Pattern | When to use | What it costs | What it scales |
|---|---|---|---|
| Configuration (props) | Small closed enum of variations; combinations are independent | Each new prop is more API surface; combinations multiply | Acceptable up to ~5-7 independent props; gets dangerous beyond |
| Composition (children, slots, sub-components) | Open-ended variation; structure matters | More code at each consumer; more concepts | Scales indefinitely; new variations are additive, not multiplicative |
Refactor sign: a configured component with >10 props that are mostly independent is a candidate for the compound-component refactor.
| Layer | Owns | Examples |
|---|---|---|
| Headless | Keyboard navigation, focus management, ARIA, internal state, event emission | Radix Primitives, Headless UI, Ariakit, React Aria, Tanstack Table |
| Styled | Visual treatment, layout, spacing, typography binding | shadcn/ui (Radix + Tailwind), Mantine, MUI theme, your design system |
The split is the architectural mechanism that solves cross-product reuse when the same interaction patterns must look different in different products. Behavior evolves independently of styling; styling evolves independently of behavior.
| Contract | Who owns value | API shape | When to use |
|---|---|---|---|
| Controlled | Consumer | value + onChange | Value participates in larger state (form, store, URL) |
| Uncontrolled | Component (internal) | defaultValue + onChange (event-shaped) | Value is the component's business alone |
| Hybrid | Both supported | Both value (controlled path) and defaultValue (uncontrolled path) | Default for any new component; serves both consumer kinds |
| Imperative-only | Refs and methods | ref.current.play(), etc. | Rare; for cases where declarative APIs are awkward (video, focus) |
Default to hybrid. Consumers choose by passing value or defaultValue. When designing state contracts (especially hybrid ones), you must preserve the primitive layer's inherent accessibility (keyboard navigation, focus management, ARIA) across all modes. Furthermore, ensure that event semantics (onChange / onValueChange) remain stable, identically shaped, and thoroughly documented regardless of whether the component is in controlled or uncontrolled mode.
| Mechanism | What it opens | When to use |
|---|---|---|
| Props (config) | Closed set of variations | Variations are small, closed, combinatorially independent |
| Children / slots | Structure | Consumer composes inner content |
Compound components (Dialog.Root, Dialog.Trigger, Dialog.Content) | Structure + implicit shared state via context | Multi-part components with structural variation |
| Render props / render functions | Rendering | Consumer overrides how something renders, with access to internal state |
| Ref exposure / imperative handles | Imperative access | Escape hatch for cases declarative APIs cannot reach (focus, scroll, play). In React 19, accept ref as a prop; use forwardRef for React 18 compatibility or libraries that still require it. |
| Polymorphism (`as` / `asChild`) | Element type | Consumer chooses the semantic tag rendered |
| Pattern | Syntax | Pros | Cons |
|---|---|---|---|
| `as` prop | <Button as="a" href="..."> | React-idiomatic; familiar | Hard to type correctly; doesn't compose well across libraries |
| `asChild` (Radix) | <Button asChild><a href="...">...</a></Button> | Cleaner accessibility; consumer sees the semantic element | Unfamiliar at first encounter |
| Slot-based (Vue, Svelte) | Framework slot mechanism | Native framework support | Limited to that framework |
For cross-library compatibility in React, asChild (and the underlying Radix Slot pattern) has become the modern default.
After applying this skill, verify:
as or asChild) — not an accidental any-tag escape hatch.| Instead of this skill | Use | Why |
|---|---|---|
| Wiring a specific product's screens from components | design-module-composition | design-module-composition owns within-product assembly; this skill owns the components being assembled |
| Designing the design system's overall structure (tokens, foundations, governance, distribution) | design-system-architecture | design-system-architecture owns meta-structure; this skill owns the component stratum |
| Picking the design language (color, type, spacing decisions) | visual-design-foundations | visual-design-foundations owns the language; this skill owns the structural mechanism delivering it |
| Deciding where component state lives across the app | state-management | state-management owns location and ownership; this skill owns the component's state-contract API surface |
| Picking React hook patterns for internal component state | Library docs (React, Vue, etc.) | Tactical implementation; below this skill |
| Designing the app's folder structure | folder-structure or frontend-architecture | This skill cares about components, not where they live on disk |
| Component-level accessibility audit | a11y | a11y owns the discipline of checking accessibility; this skill bakes the property into the architecture |
| Form-specific component architecture (validation, submit) | form-ux-architecture | form-ux-architecture owns the form-specific patterns; this skill is the broader framing |
asChild, prop spreading, ref compatibility, and primitive composition.forwardRef reference. Current React 19 ref guidance: forwardRef remains compatibility knowledge, but new React 19 components can receive ref as a prop.~30 seconds. Free. No account. Every finding cites a rule and a line of evidence.