
Polymorphic components are the Swiss Army knife of React design systems - as prop vs asChild explained
Kept running into the same problem at work: build a Button component, someone needs it as a link, now you're either duplicating styles or writing invalid html by nesting <button> inside <a>
Wrote up how polymorphic components solve this. covers:
- the as prop pattern (how chakra and mantine do it)
- making it type-safe with ComponentPropsWithoutRef<C> so typescript knows which props are valid per element
- the forwardRef gotcha where typescript loses the generic (and the fix)
- asChild pattern (how radix/shadcn does it) and why it exists
- a reusable PolymorphicProps utility type you can drop into any project
also when NOT to use any of this. not every component needs to be polymorphic.
https://www.sethi.io/blog/polymorphic-components-one-component-many-forms
Curious how others handle this in their design systems. do you go with as or asChild?