How to Use the `narrow-react-prop-types` Skill to Tighten React Component Prop Types

The narrow-react-prop-types skill is a CodeLayer-driven automation that tightens React component TypeScript prop types by deriving them from live production call sites rather than stories or test mocks.

This skill helps monorepos maintain strict, accurate prop contracts by preventing demo-only props from polluting component APIs. The workflow runs via GitHub Actions, uses an AI agent to analyze real usage patterns, and generates pull requests with narrowed type definitions.

Understanding the Core Workflow

The narrow-react-prop-types skill operates on a single principle: live code paths are the source of truth. Instead of allowing Storybook stories, test files, or mock data to dictate optional props, the skill forces type definitions to reflect only what production code actually passes.

This approach reduces unnecessary optional branches, eliminates "demo-only" props like defaultFoo, and encourages deriving types from existing values using TypeScript utilities like Parameters<typeof fn>[0] and ReturnType<typeof fn>.

Step-by-Step Execution Flow

The workflow follows a ten-step process defined in plugins/narrow-react-prop-types/skills/narrow-react-prop-types/SKILL.md:

  1. Identify suspect components flagged by previous runs or manual selection
  2. Find live usage across the monorepo, excluding test and Storybook files
  3. Analyze prop passing patterns at each call site
  4. Derive required vs. optional status based on actual usage
  5. Identify removable props never used in production
  6. Tighten type definitions in component source files
  7. Update supporting code (call sites, tests) to match new contracts
  8. Run validation (typecheck, quality checks)
  9. Generate PR with structured evidence
  10. Persist memory for iterative refinement

Key Files and Their Roles

File Path Purpose
Skill definition plugins/narrow-react-prop-types/skills/narrow-react-prop-types/SKILL.md Human-readable specification the agent follows
Response template plugins/narrow-react-prop-types/skills/narrow-react-prop-types/response-template.md PR body layout with change tables and evidence
Workflow definition .github/workflows/agent-narrow-component-props.yml GitHub Actions orchestration
Agent memory .github/agent-memory/narrow-component-props.md Persistent context between runs
Plugin metadata .claude-plugin/plugin.json Claude plugin system registration

Installing and Running the Skill

Add the Skill to Your Repository


# Install via the skills CLI

npx skills add humanlayer/skills --skill narrow-react-prop-types

This command registers the skill and copies the necessary workflow and configuration files into your repository.

Manual Workflow Dispatch

Create a custom workflow to trigger narrowing on specific components:


# .github/workflows/narrow-props.yml

name: Narrow React Props
on:
  workflow_dispatch:
    inputs:
      target_path:
        description: "Path to a specific component or package (optional)"
        required: false
        type: string

jobs:
  narrow:
    uses: ./plugins/narrow-react-prop-types/.github/workflows/agent-narrow-component-props.yml@main
    with:
      target_path: ${{ inputs.target_path }}

The reusable workflow in agent-narrow-component-props.yml handles:

  • Installing Bun and Node.js
  • Caching dependencies
  • Running bun install
  • Invoking @humanlayer/cli with claude-opus-4-8

Generated Pull Request Structure

The agent populates response-template.md to produce structured PRs:


## React Component Prop Narrowing Complete

### Summary

Narrowed props in **3** components.

### Changes Made

| Component | File | Change | Rationale |
|-----------|------|--------|-----------|
| `UserMenu` | `packages/ui/src/UserMenu.tsx` | Made `onLogout` required | All live call sites provide it |
| `DataTable` | `apps/riptide-ui/src/DataTable.tsx` | Removed `defaultSort` prop | Never used by production code |

### Live Call Sites Checked

| Call Site | File | Observation |
|-----------|------|-------------|
| `Dashboard` | `apps/riptide-ui/src/Dashboard.tsx` | Always passes `onLogout` |
| `AdminPanel` | `apps/riptide-ui/src/AdminPanel.tsx` | Provides `defaultSort` via constant |

### Validation

- [x] Typecheck passed (`bun --bun run typecheck --filter @codelayer/riptide-ui`)
- [x] Quality checks passed (`bun run quality`)

Iterative Refinement via Agent Memory

The skill supports ongoing refinement through .github/agent-memory/narrow-component-props.md. After reviewing a generated PR, team members can comment /iterate with instructions like:

  • "Exclude experimental props from narrowing"
  • "Ignore call sites in apps/admin until Q3 migration complete"
  • "Prioritize components in packages/core-ui"

The agent reads this persistent memory on subsequent runs, gradually improving its accuracy without reconfiguration.

Why This Approach Works

Preventing specification drift – Stories and tests often accumulate "convenience" props that production code never needs. Living documentation becomes misleading documentation.

DRY type definitions – Deriving prop types from actual function parameters and return values eliminates duplication between implementation and interface.

Machine-verified contracts – Every narrowed prop ships with a table of live call sites proving the change is safe. This evidence is generated, not hand-maintained.

Gradual, safe adoption – The workflow creates branches and PRs; nothing merges automatically. Teams review evidence, adjust boundaries via agent memory, and merge when confident.

Summary

Frequently Asked Questions

What distinguishes narrow-react-prop-types from a linter?

A linter enforces syntactic rules; this skill performs semantic analysis across your entire monorepo. It traces actual values passed at call sites, distinguishes production from test code, and generates evidence-backed code changes rather than just warnings.

Which files does the skill treat as "live" versus "test"?

The agent excludes paths matching common patterns: *.test.*, *.spec.*, **/__tests__/**, **/.storybook/**, and *.stories.*. Configuration in SKILL.md can customize these exclusions per repository.

Can the skill handle breaking changes to widely-used components?

Yes. The workflow flags high-usage components in the risk assessment section of generated PRs. For components with many call sites, the agent can suggest deprecation patterns or gradual migration strategies rather than immediate breaking changes.

How does agent memory persist between runs?

Context writes to .github/agent-memory/narrow-component-props.md as Markdown. This file tracks previous decisions, excluded paths, pending refactorings, and team preferences. Commenting /iterate on any generated PR appends to this memory, shaping future agent behavior without code changes.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →