What reusable components or patterns would you build
Build a layered set: design-system primitives (Button, Input, Modal, Toast), composite components (DataTable, Form, Dropdown), layout primitives (Stack, Grid), and behavioral patterns/hooks (useDisclosure, compound components, render props). Reusability comes from good APIs, not just existence.
"Reusable" isn't about quantity — it's about a layered library with clean, composable APIs that the team actually reaches for instead of rebuilding.
Layer 1 — Design-system primitives
The atoms every screen needs:
Button(variants, sizes, loading, icon slots),Input,Select,Checkbox,Radio,TextareaModal/Dialog,Drawer,Popover,TooltipToast/Notification,Badge,Avatar,Spinner,SkeletonCard,Tabs,Accordion
All consume design tokens, are fully accessible, and support controlled/uncontrolled use.
Layer 2 — Layout primitives
Composition tools that kill one-off CSS:
Stack/HStack/VStack(gap-based spacing)Grid,Box,Container,Spacer,Divider
Layer 3 — Composite / domain components
Built from primitives, encapsulating real complexity:
DataTable(sort, filter, paginate, select, virtualize)Form+FormField(validation, error display, layout)Dropdown/Combobox(search, multi-select, async options)DatePicker,FileUpload,Pagination,SearchBar,EmptyState,ErrorState
Layer 4 — Behavioral patterns (the reusable logic)
Often more valuable than components:
- Custom hooks —
useDisclosure,useDebounce,usePagination,useClickOutside,useMediaQuery - Compound components —
<Tabs><Tabs.Tab/></Tabs>for flexible structure - Render props / headless components — logic without markup (à la Radix/Headless UI), so teams style freely
- Provider patterns —
ThemeProvider,ToastProvider,AuthProvider - HOCs / wrappers —
withErrorBoundary,withAuth(used sparingly)
What makes them actually reusable
- Good API design — minimal props, sensible defaults, composable, follows native conventions (
value/onChange). - Headless where it helps — separate behavior from styling so the component survives redesigns.
- Accessible by default — keyboard, ARIA, focus management baked in.
- Documented — Storybook with examples; otherwise people rebuild it.
- Themeable via tokens, not hardcoded.
- Don't over-abstract — a component used once with five variant props is worse than two simple components.
The meta-point
Reusability is an API design discipline. A component nobody can figure out gets copy-pasted and forked. Build the primitives well, document them, and the composites fall out naturally.
Follow-up questions
- •What separates a genuinely reusable component from one that just exists?
- •What are headless components and why are they powerful?
- •When does abstracting for reuse backfire?
- •How do compound components improve a component's API?
Common mistakes
- •Equating 'lots of components' with 'good reusability'.
- •Over-abstracting — one component with a dozen variant props.
- •Skipping accessibility, so the primitives can't safely be used everywhere.
- •No documentation/Storybook, so people rebuild instead of reuse.
Performance considerations
- •Well-bounded primitives memoize cleanly and code-split well. Headless components let consumers control render cost. A bloated mega-component with many props often re-renders more than two focused ones.
Edge cases
- •A component needed in two places that are subtly different — abstract or duplicate?
- •Primitives that need to escape their own styling for one consumer.
- •Versioning a shared library without breaking consumers.
- •Third-party components that don't fit the token system.
Real-world examples
- •Radix UI / Headless UI (headless behavioral primitives) + a styled layer on top.
- •An internal design system: tokens → primitives → composites → Storybook docs.