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

book-warden

v1.0.3

Published

CLI tool for auto-generating Storybook stories for React components.

Readme

🎉 Now you can:

  • npm install
  • npx book-warden ./src/components
  • npx book-warden ./src/components --watch
  • npx book-warden ./src/components --dry-run

Absolutely — you’ve got a nice little utility script here! Let me walk you through it step by step:

💡 Big Picture

This Node.js script automates Storybook story file generation for React components in a project.

It scans your project for *.js, *.jsx, *.ts, and *.tsx files, looks for exported React components (both named and default exports), and generates corresponding .stories.jsx files using a Handlebars template.

It can also watch your filesystem for new or changed files and auto-generate stories when components are added or modified.

🧠 Key Components 1. Handlebars Template

const storyTemplate = ` import React from 'react'; import { {{componentName}} } from '{{relativeImportPath}}';

export default { title: '{{storybookTitle}}', component: {{componentName}}, };

export const Default = () => <{{componentName}} />; `;

This is the boilerplate for the Storybook story files. The placeholders {{componentName}}, {{relativeImportPath}}, and {{storybookTitle}} will be replaced when generating the file.

2.	collectGitIgnorePatterns()

Walks up from your startPath collecting .gitignore rules into an ignore instance — so it avoids generating stories for files that are ignored by Git.

3.	getAllReactFiles()

Uses glob to search recursively for files ending with .js, .jsx, .ts, or .tsx — filtering out anything matching .gitignore patterns.

4.	extractReactExports()

Uses @babel/parser and @babel/traverse to parse each file’s AST and extract: • Named exports like:

export function MyComponent() {} export class MyComponent extends React.Component {}

•	Default exports like:

export default MyComponent;

Only components that start with a capital letter (/^[A-Z]/) are considered valid React components.

5.	generateStoryFile()

For each export it finds, this: • Builds a Storybook title (using the path and component name). • Writes a .stories.jsx file to a storybook/ subfolder. • Uses the Handlebars template to format the content.

6.	processAll()

Coordinates the whole process: • Collects .gitignore rules. • Scans for React files. • Parses them for exports. • Generates stories (or logs the action if dryRun is true).

7.	runStorybooker()

The main entry point! • Runs processAll() to generate stories for existing files. • If watch mode is enabled, uses chokidar to listen for new or changed component files and generates stories for them automatically.

⚡ Usage

This script could be used in a CLI-like way by calling:

const { runStorybooker } = require('./path-to-this-script');

runStorybooker({ targetDir: '/path/to/your/react/components', dryRun: false, watch: true });

This would: • Scan the target directory. • Generate stories for any found React components. • Keep watching for new ones.

🧑‍💻 Why This is Useful

If you’ve ever worked on a component library or a large React project using Storybook, you know that manually writing .stories.jsx files for every component can get repetitive. This script automates that task and ensures consistent structure.

💡 Summary

This script: ✅ Scans for React components. ✅ Auto-generates Storybook stories using a template. ✅ Supports .gitignore filtering. ✅ Can run in dry-run or watch mode. ✅ Reduces repetitive manual work in Storybook-heavy React projects.

⸻ Great question — you’ve got a pretty neat script here! Let me break it down for you in plain English:

🧠 Purpose:

This script automates the creation of Storybook story files for your React components.

It scans a given directory (targetDir) for .js, .jsx, .ts, or .tsx files that export React components, and for each found component, it generates a corresponding .stories.jsx or .stories.tsx file using a Handlebars template.

⚙️ Key Features: • Parses React Components: Uses Babel to parse JavaScript or TypeScript files and detect exported React components (both export default and export named). • Respects .gitignore: It reads .gitignore files from the target directory and its parents, so it won’t touch files that are supposed to be ignored by Git. • Generates Storybook Files: For each detected component, it generates a Storybook file like:

import React from 'react'; import { MyComponent } from './path-to-component';

export default { title: 'Some/Nice/Path', component: MyComponent, };

export const Default = () => ;

•	Supports Watch Mode:

If you run it with --watch (-w), it will keep watching your files and automatically generate or update story files whenever you create or change a component. • Supports Dry Run: If you run it with --dryRun (-d), it will tell you what it would do without writing any files.

💡 Why This Is Useful: • Speeds up setting up Storybook stories for new components. • Enforces consistent story file structure. • Great for large codebases where writing stories by hand is repetitive. • Helps new contributors by auto-generating boilerplate stories.

💻 How You’d Run It:

node yourscript.js --targetDir ./src/components --dryRun

or

node yourscript.js --targetDir ./src/components --watch

📁 Example Scenario:

Let’s say you have a directory:

src/components/ ├── Button.tsx ├── Card.tsx └── Modal.tsx

Each exports a React component. Running this script would automatically create:

src/components/storybook/ ├── Button.Button.stories.tsx ├── Card.Card.stories.tsx └── Modal.Modal.stories.tsx

Each of these would contain the appropriate boilerplate for Storybook, ready to use!

If you want, I can help you customize the output template, or add features like prop auto-documentation too! Are you using this for a personal project or a team project?