# What Is the `narrow-react-prop-types` Skill? Purpose and Implementation Explained

> Learn about the narrow-react-prop-types skill. This automation refines React prop typings to match live code, enhancing type safety and removing optional props.

- Repository: [HumanLayer/skills](https://github.com/humanlayer/skills)
- Tags: deep-dive
- Published: 2026-09-07

---

**The `narrow-react-prop-types` skill is a CodeLayer-driven automation that tightens React component prop typings to match actual live-code usage, eliminating unnecessary optional props and improving type safety across your codebase.**

This skill is part of the [humanlayer/skills](https://github.com/humanlayer/skills) repository and represents a production-ready approach to type-safe React development. Rather than maintaining loose prop definitions that accommodate stories, tests, or mock data, the skill analyzes real-world call sites and derives precise, strict type contracts.

## How `narrow-react-prop-types` Works

The skill operates through an AI agent that examines your codebase with specific architectural goals in mind. According to the skill definition at [`plugins/narrow-react-prop-types/skills/narrow-react-prop-types/SKILL.md`](https://github.com/humanlayer/skills/blob/main/plugins/narrow-react-prop-types/skills/narrow-react-prop-types/SKILL.md), the automation follows a systematic approach to type refinement.

### Source-of-Truth Alignment

The skill identifies genuine production usage patterns—routes, wired components, providers, and actual integration points—to determine which props are truly required versus those that exist only for testing scenarios. This analysis happens at call sites rather than at the component definition, ensuring the types reflect reality.

### Strict Type Conversion

When the skill detects that an optional prop is always supplied in live code, it converts that prop to **required** or **required nullable** status. This eliminates defensive branching logic and `undefined` checks that the runtime never actually needs.

### Derivation Over Duplication

Rather than hand-writing type approximations, the skill extracts types directly from existing APIs using TypeScript utility types:

- `Parameters<typeof fn>[0]` for function parameter extraction
- `ReturnType<typeof fn>` for return shape derivation  
- `Extract<Union, Shape>` for discriminated union narrowing

As documented in [`SKILL.md`](https://github.com/humanlayer/skills/blob/main/SKILL.md) lines 69-74, this approach ensures type definitions stay synchronized with their source implementations.

### Propagation to Child Components

When narrowing a parent component affects its children, the skill cascades those type refinements downward. This maintains consistency across component hierarchies and prevents type mismatch errors at integration boundaries.

## Running the `narrow-react-prop-types` Skill

### Local Development with CLI

You can invoke the skill directly using the Humanlayer CLI:

```bash

# Install the Humanlayer CLI (if not already installed)

bunx @humanlayer/cli@latest codelayer \
  --provider anthropic \
  --model claude-opus-4-8 \
  --thinking high \
  --prompt "$(cat <<'EOF'
You are narrowing React component prop types in this repository.
Use the narrow-react-prop-types skill to identify and tighten prop typings.
EOF
)"

```

### CI/CD Integration

The skill is designed for automated execution via GitHub Actions. The workflow file at [`plugins/narrow-react-prop-types/skills/narrow-react-prop-types/references/agent-narrow-component-props.yml`](https://github.com/humanlayer/skills/blob/main/plugins/narrow-react-prop-types/skills/narrow-react-prop-types/references/agent-narrow-component-props.yml) provides the complete automation setup.

Key workflow steps include:

1. **Agent invocation** with repository context and PR number
2. **Memory persistence** via [`.github/agent-memory/narrow-component-props.md`](https://github.com/humanlayer/skills/blob/main/.github/agent-memory/narrow-component-props.md)
3. **Typecheck validation** across the entire repository
4. **PR body formatting** using the response template

A typical CI snippet:

```yaml
- name: Run CodeLayer Agent to narrow React props
  if: steps.iterate.outputs.run_agent == 'true'
  env:
    ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
    GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
  run: |
    bun ci-scripts/agent-iteration.ts \
      --command prompt \
      --workflow agent-narrow-component-props \
      --memory .github/agent-memory/narrow-component-props.md \
      --repo "${GITHUB_REPOSITORY}" \
      --pr-number "${PR_NUMBER}" \
      --comment-body "${COMMENT_BODY}" > /tmp/codelayer-prompt.md

    bunx @humanlayer/cli@latest codelayer \
      --provider anthropic \
      --model claude-opus-4-8 \
      --thinking high \
      --prompt "$(cat /tmp/codelayer-prompt.md)" \
      | tee /tmp/codelayer-output.txt

```

## Example: Prop Type Narrowing in Practice

Consider a `Card` component before and after skill application:

```tsx
// Before narrowing (accommodates stories, mocks, partial data)
interface CardProps {
  title?: string;
  onClose?: () => void;
  items?: Item[];
}

// After narrowing (based on actual production usage)
interface CardProps {
  title: string;
  onClose: () => void;
  items?: Item[];  // genuinely optional based on call site analysis
}

```

The skill determined that every production call site supplies `title` and `onClose`, making the defensive optional markers unnecessary. The resulting stricter contract simplifies the component implementation:

```tsx
// Before: Defensive code required
function Card({ title, onClose, items }: CardProps) {
  const handleClose = () => {
    if (onClose) onClose();  // Unnecessary check
  };
  // ...
}

// After: Direct usage
function Card({ title, onClose, items }: CardProps) {
  const handleClose = onClose;  // Always defined
  // ...
}

```

## Key Files in the `narrow-react-prop-types` Implementation

| File | Purpose |
|------|---------|
| [`SKILL.md`](https://github.com/humanlayer/skills/blob/main/SKILL.md) | Complete skill definition with workflow steps and requirements |
| [`references/agent-narrow-component-props.yml`](https://github.com/humanlayer/skills/blob/main/references/agent-narrow-component-props.yml) | GitHub Actions workflow for CI automation |
| [`references/narrow-component-props-memory.md`](https://github.com/humanlayer/skills/blob/main/references/narrow-component-props-memory.md) | State persistence between agent runs |
| [`references/response-template.md`](https://github.com/humanlayer/skills/blob/main/references/response-template.md) | PR body formatting template |

These files collectively implement a **CI-ready automation** that validates changes with repository-wide typechecks before submitting pull requests, as specified in [`SKILL.md`](https://github.com/humanlayer/skills/blob/main/SKILL.md) lines 45-51.

## Summary

- The `narrow-react-prop-types` skill automates the process of tightening React prop types to match actual production usage
- It converts **optional props that are always supplied** into required props, eliminating unnecessary defensive code
- The skill prefers **type derivation** (`Parameters`, `ReturnType`, `Extract`) over manual type duplication
- Changes **propagate to child components** to maintain hierarchical type consistency
- Full **CI/CD integration** via GitHub Actions enables automated, validated type refinement workflows

## Frequently Asked Questions

### Does `narrow-react-prop-types` modify test files or stories?

No. The skill explicitly excludes test files, stories, and mock data from its analysis. It targets production call sites—actual routes, wired components, and provider integrations—to ensure the narrowed types reflect real runtime requirements rather than test scaffolding.

### What happens if narrowing a prop type breaks existing code?

The skill includes a mandatory repository-wide typecheck validation step. If the narrowed types cause compilation errors in any legitimate usage, the agent detects this during CI and does not propose the breaking change. The workflow at [`agent-narrow-component-props.yml`](https://github.com/humanlayer/skills/blob/main/agent-narrow-component-props.yml) enforces this safety check before any PR is created.

### Can I run `narrow-react-prop-types` on a subset of components?

Yes. The skill accepts targeted prompts and can operate on specific component directories or files. The CLI invocation supports custom prompts that scope the agent's analysis, and the memory file mechanism allows incremental, focused refinement across multiple runs.

### How does the skill handle union type props?

The skill uses TypeScript's `Extract<Union, Shape>` utility and similar techniques to narrow discriminated unions based on actual usage patterns. Rather than maintaining broad union types that accommodate all theoretical states, it derives the specific variants encountered in production code, often collapsing complex unions to their practical subsets.