How narrow-react-prop-types Treats Storybook Stories and Support Code

The narrow-react-prop-types skill explicitly excludes Storybook stories, test files, fixtures, and mocks from prop-type derivation, allowing only live production code to determine the strictest possible TypeScript contracts.

The narrow-react-prop-types skill in the humanlayer/skills repository tightens React component prop definitions by analyzing actual usage patterns across the codebase. Rather than allowing test configurations or demo implementations to dictate optional props, this skill derives type contracts exclusively from production code paths to eliminate over-broad type definitions.

How the Skill Classifies Code Paths

Identifying Target Components

According to plugins/narrow-react-prop-types/skills/narrow-react-prop-types/SKILL.md lines 30-34, the skill first scans for suspect components displaying specific signals of over-typing. These include components with numerous optional props or callback patterns that suggest the TypeScript interface has been widened beyond what production usage actually requires.

Categorizing Call Sites

Lines 42-46 of SKILL.md establish a strict binary classification system for every call site that imports or uses the target component:

  • Live code paths: App routes, wired components, providers, hooks, production package exports, and shared components actively used in the running application (lines 44-45)
  • Support code: Storybook stories, test files, fixtures, mocks, demo harnesses, and visual-only examples (line 46)

This classification determines which usages influence the final type definition.

Excluding Support Code from Type Derivation

Storybook Stories and Test Files

Line 46 of SKILL.md explicitly defines support code as including Storybook stories, test files (.test.tsx, __tests__/), fixtures, __mocks__/, and demo harnesses. The skill treats these files as evidence of widened types rather than sources of truth for the component’s public API.

The Live-Code-Only Rule

Line 47 mandates that only live code paths determine what the component API supports. This means even if a Storybook story renders a component without providing certain props, those props will not be marked as optional if production code always supplies them. The skill treats support code as secondary documentation that must adapt to stricter production contracts.

Practical Implementation

Classifying File Types

The skill uses path-based heuristics to distinguish between production and support code. This pseudo-logic from the implementation demonstrates the classification pattern:

// Logic internal to the skill
const allUsages = findAllImports('MyComponent');
const liveUsages = allUsages.filter(u => !isSupportFile(u.filePath));
const supportUsages = allUsages.filter(u => isSupportFile(u.filePath));

// Helper: treat Storybook files as support code
function isSupportFile(path: string): boolean {
  return /(?:\.stories\.tsx?|\.test\.tsx?|__tests__|__mocks__|storybook)/.test(path);
}

Narrowing Props Based on Live Usage

After analyzing only the liveUsages, the skill transforms over-broad interfaces into strict contracts:

// Before narrowing (over-broad)
export interface MyComponentProps {
  items?: Item[];
  onSelect?: (id: string) => void; // optional for Storybook convenience
}

// After analyzing live code paths (strict)
export interface MyComponentProps {
  items: Item[];                    // now required
  onSelect: (id: string) => void;  // now required
}

Updating Support Code After Narrowing

Lines 33-35 of SKILL.md specify that when narrowing breaks existing stories or tests, developers must update the support code rather than reverting the stricter types:

// Old story (worked because props were optional)
export const Default = () => <MyComponent />;

// Updated story after narrowing (must provide required props)
export const Default = () => (
  <MyComponent
    items={sampleItems}
    onSelect={id => console.log('selected', id)}
  />
);

The skill enforces that realistic handlers and state must be provided in stories; developers cannot make live-code-path props optional again just to fix a broken Storybook file.

Implementation Details and Source Files

The narrow-react-prop-types skill relies on these key files within the humanlayer/skills repository:

File Role
plugins/narrow-react-prop-types/skills/narrow-react-prop-types/SKILL.md Full specification including the classification logic (lines 30-47), live code path definitions, and support code exclusions
plugins/narrow-react-prop-types/skills/narrow-react-prop-types/references/agent-narrow-component-props.yml Example CI workflow demonstrating skill invocation in practice
plugins/narrow-react-prop-types/.claude-plugin/plugin.json Plugin metadata used by the skills framework for integration

Summary

  • narrow-react-prop-types excludes all Storybook stories, tests, fixtures, and mocks from prop-type derivation
  • Live code paths (production imports, routes, and wired components) exclusively determine required vs. optional props
  • Support code is treated as documentation that must adapt to stricter contracts, not the reverse
  • Line 47 of SKILL.md establishes the core rule: only non-test, non-Storybook usage defines the public API
  • Broken stories after narrowing must be updated with realistic handlers and state rather than widening production types

Frequently Asked Questions

Does narrow-react-prop-types analyze Storybook files at all?

Yes, but only to classify them as support code. According to SKILL.md line 46, the skill identifies .stories.tsx files and other Storybook patterns specifically to exclude them from the type-derivation process. While it tracks these usages separately, they never influence whether a prop is marked as required or optional.

What happens when a Storybook story breaks after narrowing props?

Per lines 33-35 of SKILL.md, developers must fix the story by providing realistic handlers and state that satisfy the stricter contract. The skill explicitly forbids making live-code-path props optional again just to accommodate broken test or story files. This ensures production types remain strict while support code adapts.

How does the skill identify support code versus production code?

The skill uses regex patterns matching file paths containing .stories.tsx?, .test.tsx?, __tests__, __mocks__, or storybook (line 46 and implementation logic). All other imports—specifically those from app routes, providers, and production exports—are classified as live code paths that dictate the final type signatures.

Can I configure which files are treated as support code?

The current implementation as specified in SKILL.md uses hardcoded regex patterns to identify support files. The classification system documented in lines 42-46 treats Storybook stories, test files, fixtures, and mocks as a unified support code category without additional configuration options in the base skill definition.

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 →