{"id":14060,"library":"storycrawler","title":"Storycrawler","description":"Storycrawler is a TypeScript-first utility library designed for creating tools to crawl and interact with Storybook instances using Puppeteer. It enables developers to automate tasks such as visual regression testing, accessibility audits, and data extraction from Storybook stories by providing a structured API to manage connections to Storybook, launch and control Puppeteer browser instances, and execute tasks against individual stories. The current stable version is 5.0.1. Development is active with frequent releases, often aligning with major Storybook and Node.js LTS updates. Its key differentiators include a specialized API for managing Storybook connections, handling multiple browser workers for parallel story processing, and providing utilities like `MetricsWatcher` to ensure UI stability before interaction or data extraction. This abstracts much of the complexity typically associated with direct Puppeteer usage in a Storybook environment, making it a robust choice for build-time Storybook automation.","status":"active","version":"5.0.1","language":"javascript","source_language":"en","source_url":"https://github.com/reg-viz/storycap","tags":["javascript","storybook","puppeteer","chrome","typescript"],"install":[{"cmd":"npm install storycrawler","lang":"bash","label":"npm"},{"cmd":"yarn add storycrawler","lang":"bash","label":"yarn"},{"cmd":"pnpm add storycrawler","lang":"bash","label":"pnpm"}],"dependencies":[{"reason":"Core dependency for browser automation; `storycrawler` uses it internally and exposes Puppeteer `Page` instances for direct interaction.","package":"puppeteer","optional":false},{"reason":"The target framework this library is built to interact with. Version compatibility between `storycrawler` and the Storybook instance is crucial for correct operation.","package":"storybook","optional":false}],"imports":[{"note":"Storycrawler is an ESM-only package since v5.0.0. Named imports are the standard.","wrong":"const StorybookConnection = require('storycrawler').StorybookConnection","symbol":"StorybookConnection","correct":"import { StorybookConnection } from 'storycrawler'"},{"note":"All core classes and functions are named exports from the main package entry point.","wrong":"import StoriesBrowser from 'storycrawler/StoriesBrowser'","symbol":"StoriesBrowser","correct":"import { StoriesBrowser } from 'storycrawler'"},{"note":"This factory function is a named export for creating the story execution queue. CommonJS `require` is not supported in v5+.","wrong":"const createExecutionService = require('storycrawler').createExecutionService","symbol":"createExecutionService","correct":"import { createExecutionService } from 'storycrawler'"},{"note":"MetricsWatcher is a class used for observing and waiting for UI stability within a Storybook preview. It should be imported directly as a named export.","wrong":"import * as storycrawler from 'storycrawler'; new storycrawler.MetricsWatcher(...)","symbol":"MetricsWatcher","correct":"import { MetricsWatcher } from 'storycrawler'"}],"quickstart":{"code":"import {\n  StorybookConnection,\n  StoriesBrowser,\n  StoryPreviewBrowser,\n  MetricsWatcher,\n  createExecutionService,\n} from 'storycrawler';\n\n(async function () {\n  // Connect to the target Storybook server.\n  const storybookUrl = 'https://storybookjs.netlify.app/vue-kitchen-sink';\n  const connection = await new StorybookConnection({ storybookUrl }).connect();\n\n  // Launch Puppeteer process to fetch stories info.\n  const storiesBrowser = await new StoriesBrowser(connection).boot();\n  // Item in stories has name, kind and id of the corresponding story\n  const stories = await storiesBrowser.getStories();\n\n  // Launce Puppeteer browsers to visit each story's preview window(iframe.html)\n  const workers = await Promise.all([0, 1, 2, 3].map(i => new StoryPreviewBrowser(connection, i).boot()));\n\n  try {\n    // `createExecutionService` creates a queue of the tasks for each story.\n    const service = createExecutionService(workers, stories, story => async worker => {\n      // Display story in the worker's preview window\n      await worker.setCurrentStory(story);\n\n      // Wait for UI framework updating DOM\n      await new MetricsWatcher(worker.page).waitForStable();\n\n      // Extract information from the preview window.\n      // You can access Puppeteer's page instance via `worker.page`.\n      const m = await worker.page.metrics();\n      return { story, nodesCount: m.Nodes };\n    });\n\n    // `createExecutionService` register tasks but does not kick them.\n    // Tasks in queue start via calling `.execute()`.\n    const results = await service.execute();\n\n    results.forEach(({ story, nodesCount }) => console.log(`${story.id}: ${nodesCount}`));\n  } finally {\n    await storiesBrowser.close();\n    await Promise.all(workers.map(worker => worker.close()));\n    await connection.disconnect();\n  }\n})();","lang":"typescript","description":"This example demonstrates how to connect to a Storybook instance, fetch its stories, launch multiple Puppeteer browser workers to process each story concurrently, wait for UI stability, and extract metrics like node count using the `storycrawler` API."},"warnings":[{"fix":"Upgrade your Storybook project to version 7 or higher, or downgrade `storycrawler` to a compatible v4 release if maintaining older Storybook versions.","message":"Version 5.0.0 dropped support for Storybook versions 6 and older. Ensure your Storybook instance is on version 7 or newer for compatibility with `storycrawler` v5+.","severity":"breaking","affected_versions":">=5.0.0"},{"fix":"Upgrade your Node.js runtime environment to version 18 or newer. Check your `engines` field in `package.json`.","message":"Version 5.0.0 changed the minimum supported Node.js version to 18.x. Previous major versions supported Node.js 12.x and above.","severity":"breaking","affected_versions":">=5.0.0"},{"fix":"Migrate your consuming JavaScript/TypeScript project to use ES modules (`import`/`export` syntax). Ensure your `package.json` specifies `\"type\": \"module\"` or uses `.mjs` file extensions for module files.","message":"Version 5.0.0 transitioned `storycrawler` to be an ESM-only package. CommonJS `require()` statements are no longer supported for importing `storycrawler` modules.","severity":"breaking","affected_versions":">=5.0.0"},{"fix":"Refer to `storycrawler` and `puppeteer` documentation for recommended version pairings. Generally, updating both `storycrawler` and `puppeteer` to their latest stable versions often resolves compatibility issues.","message":"Compatibility with `puppeteer` versions is critical. `storycrawler` relies heavily on `puppeteer` for browser automation; ensure the installed `puppeteer` version is compatible with your Node.js version and the specific `storycrawler` major version.","severity":"gotcha","affected_versions":">=4.0.0"}],"env_vars":null,"search_vec":"'5.0.1':69 'abstract':119 'access':34 'activ':72 'align':77 'api':46,91 'associ':125 'audit':35 'autom':27,144 'browser':56,98 'build':141 'build-tim':140 'choic':138 'chrome':148 'complex':123 'connect':49,95 'control':54 'crawl':15 'creat':12 'current':65 'data':37,116 'design':10 'develop':25,70 'differenti':87 'direct':127 'enabl':24 'ensur':110 'environ':133 'execut':59 'extract':38,117 'first':7 'frequent':74 'handl':96 'includ':88 'individu':62 'instanc':20,57 'interact':17,114 'javascript':145 'key':86 'launch':52 'librari':9 'like':107 'lts':83 'major':79 'make':134 'manag':48,93 'metricswatch':108 'much':120 'multipl':97 'node.js':82 'often':76 'parallel':101 'process':103 'provid':43,105 'puppet':22,55,128,147 'regress':32 'releas':75 'robust':137 'special':90 'stabil':112 'stabl':66 'stori':41,63,102 'storybook':19,40,51,80,94,132,143,146 'storycrawl':1,2 'structur':45 'task':28,60 'test':33 'time':142 'tool':13 'typescript':6,149 'typescript-first':5 'typic':124 'ui':111 'updat':84 'usag':129 'use':21 'util':8,106 'version':67 'visual':31 'worker':99","created_at":"2026-04-20T01:57:43.875118+00:00","updated_at":"2026-04-20T01:57:43.875118+00:00","problems":[{"fix":"Replace `require()` statements with ES module `import` syntax. Ensure your project is configured for ESM (e.g., `\"type\": \"module\"` in `package.json`).","cause":"Attempting to use CommonJS `require()` syntax with `storycrawler` v5+, which is an ESM-only package.","error":"ReferenceError: require is not defined"},{"fix":"Verify that the `storybookUrl` provided to `StorybookConnection` is correct and that your Storybook server is running and accessible. Check any firewall or network proxy settings, or consider increasing the `serverTimeout` option if the server is slow to start.","cause":"`storycrawler` failed to establish a connection with the target Storybook server, possibly due to an incorrect URL, the server not running, or network configuration issues.","error":"Error: Storybook connection timed out"},{"fix":"Implement robust waiting strategies using `MetricsWatcher.waitForStable()`, `worker.page.waitForSelector()`, or `worker.page.waitForFunction()` before interacting with elements. Double-check your CSS selectors for accuracy and specificity against the Storybook version you are targeting.","cause":"A CSS selector used within Puppeteer methods (`worker.page.$()`, `worker.page.click()`, etc.) could not locate the intended DOM element in the Storybook preview iframe. This often indicates a timing issue, an incorrect selector, or a change in Storybook's DOM structure.","error":"Error: Failed to find element matching selector \"[data-story-id='some-story-id']\""},{"fix":"Increase the navigation timeout via Puppeteer options. Review the story for any blocking resources or extremely long rendering times. Ensure the Storybook server is performing optimally.","cause":"The Storybook preview iframe failed to load or navigate to the story's HTML within the expected timeout, potentially due to a slow Storybook server, complex story rendering, or a network issue.","error":"Error: Navigation to preview HTML timed out or failed."}],"ecosystem":"npm","meta_description":null,"install_score":null,"quickstart_score":null,"quickstart_tag":null,"pypi_latest":null,"cli_name":"","cli_version":null,"type":"library","homepage":null,"github":"https://github.com/reg-viz/storycap","docs":null,"changelog":null,"pypi":null,"npm":"https://www.npmjs.com/package/storycrawler","openapi_spec":null,"status_page":null,"smithery":null,"categories":["testing","web-framework","devops"],"base_url":null,"auth_type":null,"provenance":{"verified_status":null,"verified_at":null,"last_verified":"2026-06-17","next_check":"2026-07-18","install_tag":null}}