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:
- Identify suspect components flagged by previous runs or manual selection
- Find live usage across the monorepo, excluding test and Storybook files
- Analyze prop passing patterns at each call site
- Derive required vs. optional status based on actual usage
- Identify removable props never used in production
- Tighten type definitions in component source files
- Update supporting code (call sites, tests) to match new contracts
- Run validation (typecheck, quality checks)
- Generate PR with structured evidence
- 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/cliwithclaude-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
experimentalprops from narrowing" - "Ignore call sites in
apps/adminuntil 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
- The
narrow-react-prop-typesskill automates prop type tightening using live call sites as the source of truth - Execution runs via
agent-narrow-component-props.yml, invoking Claude Opus through the CodeLayer CLI - The ten-step process in
SKILL.mdguides the agent from identification through validation .github/agent-memory/narrow-component-props.mdenables iterative refinement between runs- Generated PRs follow
response-template.mdwith structured evidence tables for review
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:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →