Skip to main content
Arthur Ha

React Patterns

Composition Over Configuration - Let Consumers Build, Not Configure

March 3, 2026

The more your component does, the more props it needs. showHeader, showFooter, isCompact, variant="thread". Before long you're passing a dozen flags and nobody can tell what the component will actually render. There's a simpler approach: composition over configuration. Give consumers building blocks and let them assemble the UI they need.

The problem: one component, too many knobs

Imagine a message composer used in channels, threads, and edit mode. It's tempting to drive everything with props:

TSX
<Composer
  isThread
  isEditing={false}
  channelId="abc"
  showAttachments
  showFormatting={false}
  renderCustomFooter={() => <MentionPicker />}
/>

What does this render? You have to trace through conditionals. Adding a new use case means another prop. The API grows and the component becomes a configuration surface instead of a clear, composable UI.

The fix: expose pieces, let consumers compose

Instead of one configurable component, expose small pieces and let the caller arrange them:

TSX
// Channel composer - only what a channel needs
function ChannelComposer() {
  return (
    <Composer.Frame>
      <Composer.Header />
      <Composer.Input />
      <Composer.Footer>
        <Composer.Attachments />
        <Composer.Formatting />
        <Composer.Emojis />
        <Composer.Submit />
      </Composer.Footer>
    </Composer.Frame>
  );
}

// Thread composer - adds "also send to channel"
function ThreadComposer({ channelId }: { channelId: string }) {
  return (
    <Composer.Frame>
      <Composer.Header />
      <Composer.Input />
      <AlsoSendToChannelField id={channelId} />
      <Composer.Footer>
        <Composer.Formatting />
        <Composer.Emojis />
        <Composer.Submit />
      </Composer.Footer>
    </Composer.Frame>
  );
}

Each screen composes only what it needs. No booleans, no hidden behavior. The code reads like the UI: structure is explicit and easy to change. That's composition over configuration - fewer props, clearer intent, and components that scale.