All topics
Patternsadvanced

Headless Components

Learn the philosophy of separating behavior/accessibility logic from visual presentation entirely, letting consumers own all markup and styling.

Headless components (or headless UI hooks) provide all the *behavior* of a UI widget — state management, keyboard interactions, focus management, ARIA attributes — without rendering any visual markup or applying any styling themselves. The consumer supplies 100% of the JSX and CSS, typically wiring it up using a prop getters API or by directly consuming returned state and handler functions.

A headless component is like hiring a choreographer who teaches dancers (your components) exactly which moves and timing to use (behavior and accessibility) but has no opinion on their costumes (visual styling) — you dress the performance however fits your production.

Key Concepts

1
This fully decouples 'how a combobox behaves' from 'what a combobox looks like,' which solves a recurring pain point with traditional component libraries: adopting a styled component library often means either accepting its visual design wholesale or fighting CSS specificity wars to override it. A headless library sidesteps this entirely since there's no default visual output to override — you always build your own.
2
Popular examples include Downshift and React Aria for behavior-only widgets, and Radix UI / Headless UI for a broader set of interactive primitives (dialogs, menus, tooltips) that ship correct accessibility and interaction behavior while leaving all visual styling to the consumer's own CSS or component library (like Tailwind).
3
Interviewers exploring component library design ask candidates to weigh headless components against fully-styled component libraries — a strong answer identifies the tradeoff explicitly: headless gives full design control and avoids CSS override fights, at the cost of needing to build (or already have) your own visual design system on top.