component-api

Installation
SKILL.md

Designing a Component's Prop Contract

The default posture: the zero-prop render is the product. <Component /> with nothing passed should be the version you would ship to a customer — right defaults, right motion, right spacing — and every prop that follows exists to turn something off or move it somewhere else, never to assemble the component from parts. Benji Taylor puts it flatly in /drawesome: "It's opinionated, and that's the point. The defaults are meant to be the version you ship… Everything below is turning things off or moving them around, not rebuilding it." A component that needs eleven props before it looks right is not a component; it is a template with extra steps. This skill owns the prop contract of any component. forms owns what a field does — layout, validation timing, autofill tokens — and ui-states owns which non-happy-path states a component must be able to render; come here only for the shape of the API that exposes them.

Read the project's component conventions before designing anything. Look for an existing primitives layer (Radix, Base UI, Ark, shadcn/ui, Headless UI), an existing variant mechanism (CVA, tailwind-variants, vanilla-extract recipes, styled-components), and the React version — on React 19 ref is a plain prop and forwardRef is dead weight. Match whatever is there. If the codebase spells variants with CVA, your component spells variants with CVA; a second variant system is a permanent tax on everyone who touches the folder afterwards.

Quick Reference

Topic Reference Open it when
Working code: context, dual-mode state, asChild, refs, slots, invisible edge cases, file layout references/implementation.md Open it when you have settled the API shape and are about to write the component, and you need the exact code rather than the rule.

Core Principles

  1. Ship the defaults, not the knobs. Most consumers never customize, so the defaults are the design. Emil Kowalski's second Sonner principle — good defaults matter more than options — is why a library at 13M+ weekly downloads is usually installed and never configured. Concretely: variant = "primary", size = "md", type = "button" (never "submit"), and a setup cost of one mounted <Toaster /> with no hooks and no context to wire. Exception: a headless primitive whose entire purpose is to have no opinion (Slot, VisuallyHidden) ships behavior with zero visual defaults.

  2. Every prop subtracts or relocates; no prop rebuilds. Benji's Liveline exposes 2 props, and its maximalist mode (degen) is opt-in and off by default — maximalism is an escape hatch, never the shipped state. The test is falsifiable: if removing a prop would leave the component unable to render, it is not configuration, it is a missing default. Fix the default instead of documenting the prop. Exception: a component that wraps a spec'd element (<input>, <a>) inherits that element's whole attribute surface through {...props}; those do not count against the budget because you did not design them.

Installs
3
Repository
agentsorg/benji
GitHub Stars
1
First Seen
Aug 2, 2026
component-api — agentsorg/benji