Design System Glossary

Render Props

Render props is a pattern where a component accepts a function as a prop, and that function determines what to render. Instead of prescribing child elements, the component calls the function and renders its return value. It's a way to expose internal state and logic without forking the component.

Classic example in React:

<Menu open={isOpen} trigger={<button>Menu</button>}> {(items) => ( <ul> {items.map(item => <li key={item.id}>{item.label}</li>)} </ul> )} </Menu>

The Menu component manages open/close state, keyboard navigation, and positioning. The caller decides what DOM to render for the items. This separates logic (Menu's responsibility) from presentation (caller's responsibility).

For Design Systems, render props shine when you need to:

Support multiple layouts without creating variants. A List component can render as a vertical menu, a dropdown, a horizontal breadcrumb — all with the same logic. Give callers access to component internals (highlighted item, hover state) without exposing the full component API. Avoid wrapper bloat. Instead of SelectWithChips, SelectWithIcons, SelectWithBadges, you have one Select that accepts a render function.

The downside: complexity. A render prop component is harder to understand and document than a simple component. It's also less discoverable — callers have to read docs to know what data the function receives.

Modern alternatives — scoped slots in Vue, the children function pattern in React — solve the same problem with different syntax. The pattern name matters less than the principle: let the component manage logic and state, and let the caller control the DOM.

Related: Component API · Slots · Headless components · Composability