Extract structured information about React components and their props through AST parsing. See also: react-analyzer-mcp
Ideal for:
- Feeding high level codebase structure to LLMs
- Building developer tools / visual component editors / component catalogs (e.g storybooks)
- Performing static analysis
- Documentation generation
Included:
- Supports JSX and TSX files
- Extracts component names, props, and their types
- Supports complex TypeScript types
- Handles React.FC, React.memo, and React.forwardRef
- Detects default props (
({ items = [] })and prop types (component.propTypes =) - Processes generic types and utility types
Demo:
Scope:
Focused on React component analysis but internally scans all variables, functions, interfaces in given files. Can be extended for other frameworks, etc.
npm install azer/react-analyzerCompile:
npm run buildRun tests:
npm run testimport{analyzeReactFile}from'react-analyzer';// Analyze a React fileconstresult=analyzeReactFile('MyComponent.tsx',sourceCode);exportfunctionHelloWorld(props){return<div>{props.user}: {props.message}</div>}Analysis result:
{type: 'jsx',filename: 'HelloWorld.jsx',components: [{name: 'HelloWorld',props: {message: {type: 'unknown',optional: false},user: {type: 'unknown',optional: false}}}]}interfaceProps{name: string;age: number;isActive?: boolean;}exportconstMyComponent=({ name, age, isActive }: Props)=>{return<div>{name}: {age}</div>;};constFoo=MyComponentconstBar=Fooexport{Bar}Analysis result:
{type: 'tsx',filename: 'MyComponent.tsx',components: [{name: 'MyComponent',props: {name: {type: 'string',optional: false},age: {type: 'number',optional: false},isActive: {type: 'boolean',optional: true},},},{name: 'Bar',props: {name: {type: 'string',optional: false},age: {type: 'number',optional: false},isActive: {type: 'boolean',optional: true},},}]}interfaceItem{id: string;name: string;}interfaceComplexWrappedComponentProps{items: Item[];onItemSelect: (item: Item)=>void;initialCount?: number;}constComplexWrappedComponent: React.FC<ComplexWrappedComponentProps>=React.memo(({ items, onItemSelect, initialCount =0})=>{return(<div><h2>Selected: {initialCount}</h2><ul>{items.map((item)=>(<likey={item.id}onClick={()=>onItemSelect(item)}>{item.name}</li>))}</ul></div>);});exportdefaultComplexWrappedComponent;Analysis result:
{type: 'tsx',filename: 'ComplexComponent.tsx',components: [{name: 'ComplexWrappedComponent',props: {items: {type: 'array',optional: false,elementType: {type: 'object',props: {id: {type: 'string',optional: false},name: {type: 'string',optional: false}},typeName: 'Item'}},onItemSelect: {type: 'function',optional: false,parameters: [{type: 'object',props: {id: {type: 'string',optional: false},name: {type: 'string',optional: false}},typeName: 'Item'}],returnType: {type: 'void'}},initialCount: {type: 'number',optional: true,defaultValue: '0'}},wrapperFn: 'React.memo'}]}