{"id":11849,"library":"react-scanner","title":"React Component & Prop Usage Scanner","description":"react-scanner is a static analysis tool designed to extract React component and prop usage from source code, supporting both JavaScript and TypeScript. It operates by crawling a specified directory, identifying relevant files, and then parsing them to build a detailed JSON report of component instances and their associated prop values. The current stable version is 1.2.0, with a history of regular updates indicating active maintenance and feature development. Key differentiators include its static analysis approach, eliminating the need for runtime instrumentation, robust TypeScript support, and a flexible architecture that allows for custom processors to transform the raw JSON output into actionable insights, such as component usage counts or prop value distributions. It is primarily used for understanding the adoption and utilization patterns of design system components within a codebase.","status":"active","version":"1.2.0","language":"javascript","source_language":"en","source_url":"https://github.com/moroshko/react-scanner","tags":["javascript","react","scanner","component","components","jsx","usage","info","stats"],"install":[{"cmd":"npm install react-scanner","lang":"bash","label":"npm"},{"cmd":"yarn add react-scanner","lang":"bash","label":"yarn"},{"cmd":"pnpm add react-scanner","lang":"bash","label":"pnpm"}],"dependencies":[],"imports":[{"note":"The primary `scan` function is exported as a default export from the main package entry point.","wrong":"import { scan } from 'react-scanner';","symbol":"scan","correct":"import scan from 'react-scanner';"},{"note":"Built-in processors like `countComponents` are located in the `react-scanner/processors` submodule.","wrong":"import { countComponents } from 'react-scanner';","symbol":"countComponents","correct":"import { countComponents } from 'react-scanner/processors';"},{"note":"When using TypeScript, `Config` should be imported as a type for defining the scanner's configuration object.","wrong":"import { Config } from 'react-scanner';","symbol":"Config","correct":"import type { Config } from 'react-scanner';"}],"quickstart":{"code":"import { mkdir, writeFile, rm } from 'node:fs/promises';\nimport { join } from 'node:path';\nimport scan from 'react-scanner';\n\nasync function runScanner() {\n  const tmpDir = join(process.cwd(), 'tmp-scanner-test');\n  await mkdir(tmpDir, { recursive: true });\n\n  const jsxContent = `\n    import React from 'react';\n    import { Button, Card } from './components';\n\n    function App() {\n      return (\n        <div>\n          <Button label=\"Click Me\" onClick={() => console.log('clicked')} />\n          <Card title=\"Hello\" description=\"This is a test card\" />\n          <Button label=\"Submit\" variant=\"primary\" />\n        </div>\n      );\n    }\n    export default App;\n  `;\n  await writeFile(join(tmpDir, 'App.jsx'), jsxContent);\n\n  const componentsContent = `\n    import React from 'react';\n    export const Button = ({ label, onClick, variant }) => <button>{label}</button>;\n    export const Card = ({ title, description }) => <div><h3>{title}</h3><p>{description}</p></div>;\n  `;\n  await writeFile(join(tmpDir, 'components.js'), componentsContent);\n\n  const config = {\n    rootDir: tmpDir,\n    excludedPaths: [],\n    processors: [],\n    getComponentName: ({ local }) => local,\n    getPropValue: ({ value }) => value && value.type === 'JSXExpressionContainer' ? '(Identifier)' : value\n  };\n\n  try {\n    console.log('Scanning React components...');\n    const report = await scan(config);\n    console.log('Generated Report:\\n', JSON.stringify(report, null, 2));\n  } catch (error) {\n    console.error('Error during scanning:', error);\n  } finally {\n    await rm(tmpDir, { recursive: true, force: true });\n    console.log(`Cleaned up temporary directory: ${tmpDir}`);\n  }\n}\n\nrunScanner();","lang":"typescript","description":"Demonstrates programmatic use of `react-scanner` to scan a temporary React project and print the raw JSON report. It shows how to configure the scanner with basic options like `rootDir`, `getComponentName`, and `getPropValue` to analyze component and prop usage."},"warnings":[{"fix":"Update your `react-scanner` configuration to include `getComponentName: ({ local }) => local` if you need to replicate the component name extraction logic from versions prior to 0.5.0.","message":"The `getComponentName` configuration option was introduced in version 0.5.0. If you were relying on previous implicit component name extraction, you must explicitly configure `getComponentName: ({ local }) => local` to maintain the old behavior.","severity":"breaking","affected_versions":">=0.5.0"},{"fix":"Ensure your scanning process handles a non-zero exit code if it's acceptable for no files to be found. Adjust CI/CD scripts to either validate file existence before running the scanner or to explicitly allow a non-zero exit code in this scenario.","message":"When no files are found to scan based on the provided configuration, `react-scanner` will now exit with an exit code of 1. This change, introduced in version 0.6.0, can cause CI/CD pipelines to fail if they expect a 0 exit code even for empty scan results.","severity":"gotcha","affected_versions":">=0.6.0"}],"env_vars":null,"last_verified":"2026-04-19T00:00:00.000Z","next_check":"2026-07-18T00:00:00.000Z","problems":[{"fix":"Add nullish coalescing or optional chaining (`?.`) when accessing properties within your custom configuration functions, e.g., `value && value.type` or `value?.type`.","cause":"This error often occurs in custom `getPropValue` or `getComponentName` functions when attempting to access properties of a `value` or `local` object that might be `null` or `undefined` for certain AST nodes.","error":"TypeError: Cannot read properties of undefined (reading 'type')"},{"fix":"Ensure your configuration object explicitly includes a `rootDir` property pointing to the base directory for scanning, e.g., `{ rootDir: './src' }`.","cause":"The `rootDir` property is missing or empty in the `react-scanner` configuration object. Since version 0.3.0, configurations are strictly validated.","error":"Error: Configuration is not valid. 'rootDir' is required."}],"ecosystem":"npm"}