From stories to API documentation

Stories show “how it looks.” Documentation explains “when to use,” constraints, and the props contract. In Storybook that is a mix of Autodocs and hand-written MDX.

Autodocs

With autodocs enabled, Storybook builds a page:

  • description from JSDoc / parameters.docs.description;
  • props table (from PropTypes or TypeScript);
  • primary story + the rest as examples.
/**
 * Primary action button in the product.
 * Keep one primary per screen.
 */
export default {
  title: 'Components/Button',
  component: Button,
  tags: ['autodocs'],
  parameters: {
    docs: {
      description: {
        component: 'Button with variants, sizes, and a loading state. Use the native type.',
      },
    },
  },
};

To make the props table useful:

  • types must be explicit (variant: 'primary' | 'secondary' | …);
  • props need short JSDoc;
  • defaultValue is reflected in code or argTypes.

MDX: when a hand-written page is better

Autodocs does not replace guidelines. MDX is needed for:

  • Do / Don’t with images;
  • composition patterns (Card + Badge);
  • migration notes;
  • tokens and principles not tied to one component.
import { Meta, Canvas, Controls } from '@storybook/blocks';
import * as ButtonStories from './Button.stories';

<Meta of={ButtonStories} />

# Button

Use **one** primary per view.

<Canvas of={ButtonStories.Primary} />
<Controls of={ButtonStories.Primary} />

## Do not

- Two primaries in a row in one toolbar.
- Icon-only without aria-label.

Structure of a good component page

  1. Purpose — in one sentence.
  2. When to use / when not.
  3. Examples (Canvas) — key states.
  4. Props — table + notes on non-obvious ones.
  5. A11y — keyboard, names, contrast.
  6. Related components — links to Input Field, IconButton, etc.

Props table: data quality

Bad: props: any, empty descriptions.
Good: enums, defaults, “deprecated” markers.

For React + TypeScript, Storybook reads types via docgen. Ensure the component export and its props interface are visible to the analyzer (not only an internal const without export type).

Document behavior, not only appearance

  • What loading does with disabled and aria.
  • How ref is forwarded.
  • Controlled vs uncontrolled mode (Modal open).
  • Constraints: “do not put a button inside Card-as-link.”

Practice

  1. Enable autodocs for Button, Input, Card.
  2. Add JSDoc on public props.
  3. Write MDX with Do/Don’t for Button.
  4. Ask a colleague to build UI only from Storybook — gaps in the docs will become obvious.