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

> Learn how narrow-react-prop-types excludes Storybook stories and test code. It derives TypeScript contracts only from live production code for maximum strictness.

- Repository: [HumanLayer/skills](https://github.com/humanlayer/skills)
- Tags: internals
- Published: 2026-09-12

---

**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`](https://github.com/humanlayer/skills/blob/main/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`](https://github.com/humanlayer/skills/blob/main/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`](https://github.com/humanlayer/skills/blob/main/SKILL.md) explicitly defines support code as including **Storybook stories**, test files ([`.test.tsx`](https://github.com/humanlayer/skills/blob/main/.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:

```typescript
// 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:

```typescript
// 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`](https://github.com/humanlayer/skills/blob/main/SKILL.md) specify that when narrowing breaks existing stories or tests, developers must **update the support code** rather than reverting the stricter types:

```tsx
// 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`](https://github.com/humanlayer/skills/blob/main/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`](https://github.com/humanlayer/skills/blob/main/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`](https://github.com/humanlayer/skills/blob/main/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`](https://github.com/humanlayer/skills/blob/main/SKILL.md) line 46, the skill identifies [`.stories.tsx`](https://github.com/humanlayer/skills/blob/main/.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`](https://github.com/humanlayer/skills/blob/main/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`](https://github.com/humanlayer/skills/blob/main/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.