All skills
Skillintermediate

architecture avoid boolean props

Don't add boolean props like `isThread`, `isEditing`, `isDMThread` to customize component behavior. Each boolean doubles possible states and creates unmaintainable conditional logic. Use composition instead.

Claude Code Knowledge Pack7/10/2026

Overview

Avoid Boolean Prop Proliferation

Don't add boolean props like isThread, isEditing, isDMThread to customize component behavior. Each boolean doubles possible states and creates unmaintainable conditional logic. Use composition instead.

Incorrect (boolean props create exponential complexity):

function Composer({
  onSubmit,
  isThread,
  channelId,
  isDMThread,
  dmId,
  isEditing,
  isForwarding,
}: Props) {
  return (
    <form>
      
      
      {isDMThread ? (
        
      ) : isThread ? (
        
      ) : null}
      {isEditing ? (
        
      ) : isForwarding ? (
        
      ) : (
        
      )}
      
    </form>
  )
}

Correct (composition eliminates conditionals):

// Channel composer
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" field
function ThreadComposer({ channelId }: { channelId: string }) {
  return (
    <Composer.Frame>
      <Composer.Header />
      <Composer.Input />
      
      <Composer.Footer>
        <Composer.Formatting />
        <Composer.Emojis />
        <Composer.Submit />
      </Composer.Footer>
    </Composer.Frame>
  )
}

// Edit composer - different footer actions
function EditComposer() {
  return (
    <Composer.Frame>
      <Composer.Input />
      <Composer.Footer>
        <Composer.Formatting />
        <Composer.Emojis />
        <Composer.CancelEdit />
        <Composer.SaveEdit />
      </Composer.Footer>
    </Composer.Frame>
  )
}

Each variant is explicit about what it renders. We can share internals without sharing a single monolithic parent.