npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@component-anatomy/storybook

v0.4.0

Published

Storybook addon — interactive component anatomy panel synced with the story canvas

Readme

@component-anatomy/storybook

Storybook addon that adds an Anatomy panel — an interactive part list synced two-way with the story canvas.

  • Hover a part in the panel → the element is highlighted in the canvas
  • Hover a data-part element in the canvas → the panel entry activates
  • The same table renders inside MDX via @component-anatomy/storybook/blocks
  • Works with Storybook 10 and 11, any renderer (React, Vue, HTML, Web Components…)

Install

npm install --save-dev @component-anatomy/storybook

Register the addon in .storybook/main.ts. This is what loads the Anatomy panel into the Storybook manager:

// .storybook/main.ts
export default {
  addons: ['@component-anatomy/storybook'],
};

If your preview.ts uses CSF Next

CSF Next is the default story format in Storybook 11. A preview.ts built with definePreview composes only the addons it lists, and Storybook drops the preview annotations that main.ts would otherwise contribute — so the addon also has to be registered there, or the canvas decorator never mounts and the panel stays empty:

// .storybook/preview.ts

// Replace your-framework with the framework you are using (e.g. react-vite, nextjs-vite)
import { definePreview } from '@storybook/your-framework';
import componentAnatomy from '@component-anatomy/storybook';

export default definePreview({
  // ...rest of preview
  addons: [componentAnatomy()], // 👈 register the addon here
});

Registering in both places is correct and safe: the two paths are mutually exclusive, so the decorator is composed exactly once either way. A preview.ts that is still a plain object needs only the main.ts entry above.

Doing so also types parameters.anatomy across that preview's metas and stories, so the shape below is checked for you.

Use

Annotate your story's DOM with data-part and add the anatomy parameter:

import type { AnatomyParameters } from '@component-anatomy/storybook';

export const Anatomy: Story = {
  parameters: {
    anatomy: {
      parts: [
        { id: 'icon',  name: 'Icon',  description: 'Optional leading glyph.' },
        { id: 'label', name: 'Label', description: 'The visible action text.' },
      ],
      // optional:
      preset: 'blueprint',            // 'default' | 'minimal' | 'contrast' | 'blueprint'
      theme: { accent: '#0d9488' },   // theme tokens for the canvas overlays
      overlayLabel: true,             // floating name chip
      overlayPadding: 2,              // inflate highlight boxes (px)
      root: '.my-component',          // narrow the anatomy root (CSS selector)
      disable: false,                 // turn off for a story
    } satisfies AnatomyParameters,
  },
};

Omit parts (pass {}) and the panel lists parts auto-discovered from data-part attributes, with names derived from the ids.

preset and theme reach the panel and the <Anatomy> block too, not just the canvas overlays: the active row is accented with the same color the overlay paints. Where that color would be illegible on Storybook's own panel — contrast is black, the manager is dark by default — the table falls back to the most colorful alternative that meets WCAG AA, so contrast accents with its yellow on a dark panel and with black on a light one.

Parameters follow Storybook's normal inheritance — project-wide defaults in .storybook/preview.ts, per-component in meta.parameters, per-story overrides in story.parameters.

In MDX

The panel's table also renders inline in a docs page, so anatomy can sit in the prose next to the preview. Requires @storybook/addon-docs (the addon that renders MDX), which stays an optional peer dependency — the panel above works without it.

import { Meta } from '@storybook/addon-docs/blocks';
import { Anatomy } from '@component-anatomy/storybook/blocks';

import * as ButtonStories from './Button.stories';

<Meta of={ButtonStories} />

<Anatomy of={ButtonStories.Anatomy} />

<Anatomy> renders the canvas and the table together, tightened into one pairing, with the canvas's show-code button dropped by default (chrome that mostly restates what the table already documents). Hover sync works both ways, exactly as in the panel.

| Prop | Type | Description | |---|---|---| | of | CSF export | The story to document, or a whole CSF module to read the meta's parameters. Omit on an attached docs page (one with <Meta of={…} />) to fall back to the page's current story. | | parts | AnatomyPartDefinition[] | Curated list, overriding both parameters.anatomy.parts and auto-discovery. | | sync | boolean | Two-way hover sync with the rendered story. Default true. false gives a purely static table. | | sourceState | 'hidden' \| 'shown' \| 'none' | Passed to the underlying <Canvas>. Default 'none' — set it to keep the show-code button. |

For a hand-placed canvas — a custom layout, or one that keeps its source panel some other way — use <AnatomyTable> next to your own <Canvas> instead. It takes the same of, parts and sync props, minus sourceState, which is <Canvas>'s concern:

import { Canvas, Meta } from '@storybook/addon-docs/blocks';
import { AnatomyTable } from '@component-anatomy/storybook/blocks';

import * as ButtonStories from './Button.stories';

<Meta of={ButtonStories} />

<Canvas of={ButtonStories.Anatomy} />
<AnatomyTable of={ButtonStories.Anatomy} />

Two things worth knowing, for either block:

  • Auto-discovery needs the story's canvas on the page. Parts are read from the story's data-part attributes as it renders, so a block that relies on discovery needs a canvas on the same page — <Anatomy> brings its own, <AnatomyTable> needs a <Canvas of={…} /> (or <Story of={…} />) next to it. A block with an explicit parts list stands on its own.
  • A meta has no canvas. of={ButtonStories} reads meta.parameters.anatomy, but there is nothing to discover parts from or to sync hover with — give it parts explicitly, and use <AnatomyTable> rather than <Anatomy> since there is no story to draw a canvas from.

Several blocks can share one page; each talks only to the story it names.

Compatibility

| | | |---|---| | storybook | ^10.0.0 \|\| ^11.0.0-0 | | @storybook/addon-docs | ^10.0.0 \|\| ^11.0.0-0 (optional — only for the MDX blocks) | | react | >=18 (optional — only for the MDX blocks) | | Node | >=22.12.0 |

The package is ESM-only, like Storybook itself since 9. Storybook 9 is no longer supported: CSF Next registration needs definePreviewAddon, which Storybook only ships from 9.1 onwards, and the addon is built and tested against 10 and 11.

Example

A complete Storybook 11 setup with Button/Slider/Tabs stories — and two MDX pages using the <Anatomy> block — lives in examples/storybook, deployed at https://julien-deramond.github.io/component-anatomy/storybook/.

Docs

Full documentation: https://julien-deramond.github.io/component-anatomy/docs/storybook

License

MIT