The React composition ladder: avoiding prop overload and overengineering 🧗‍♂️
Orus’s four React composition levels: plain props, compound components, Composer with Providers and state behind a contract.

As a project grows, every frontend runs into one of two extremes: either components expand to dozens of props (isCollapsed, leadingIcon, customTitle, etc.), or developers immediately wrap everything in global providers and contexts.
The Orus team published an excellent article on organizing component composition into a four-step “abstraction ladder”. The main rule: always start at the cheapest, lowest level and climb only when a specific pain point appears.
Here is what their ladder looks like:
- Plain Props The basic level where the overwhelming majority of UI components should stay. A pure function of props, without magic.
- Compound Components
When a component starts accumulating flags for every little thing, slots and a compound structure (
Item.Root,Item.Media) replace props such asleadingortrailing. The component owns the layout and styles but hands control over its contents to the caller. - Composer + Providers (separating UI and data)
Comes into play when the same UI must display data from different sources (for example, lists of active deals, archived deals or test mocks). The layout moves into a
Composer(which reads the data contract and does not know where the data came from), while data is supplied through interchangeableProviders. - Lifted State behind a Contract The top of the ladder, where complex interactive state moves outside the UI component through an interface/contract, keeping the layout itself “clean.”
When NOT to climb the ladder:
- For “consistency” (when every feature is forced into the same architectural mold).
- When there is exactly one data source and no alternatives are expected in the foreseeable future.
- For local state that never leaves the component.