react-component-scanner
v1.0.3
Published
A powerful tool to scan React/React Native codebases and generate component dependency graphs with collision resolution and import analysis
Maintainers
Readme
React Component Scanner
A powerful tool to scan React, React Native, Next.js, and Vite codebases and generate comprehensive component dependency graphs with advanced collision resolution and import analysis.
Disclaimer
This project is completely vibe-coded with no coding standard whatsoever. If you want to contribute, you should use Curser.
Why this package
⚠️ This package is not intended to be used on its own.
It was designed to work alongside React Graph, a web-based UI tool that visualizes your component tree and unlocks powerful features using the output generated by this package as input.
🚀 Features
- Auto Project Detection: Automatically detects project root for React, React Native, Next.js, Vite, and other frameworks
- Component Discovery: Automatically finds all React components (function, class, arrow, forwardRef, memo)
- Dependency Graph: Maps parent-child relationships between components
- Collision Resolution: Handles multiple components with the same name using hash-based unique IDs
- Import Analysis: Resolves imports with re-export following and path alias support
- Same-File Priority: Prioritizes components defined in the same file over external imports
- 🤖 Automatic Screen Detection: Automatically detects screens from navigation patterns (NEW!)
- React Navigation: Stack.Screen, Tab.Screen, Drawer.Screen patterns
- React Router: Route element/component patterns
- Next.js: File-based routing (pages/ and app/ directories)
- Manual Screen Detection: Identifies screen components based on ScreenContainer usage or manual marking
- Navigation Flow: Extracts navigation sequences from component properties
- Entry Route Detection: Identifies application entry points
- Babel Integration: Dynamically reads path aliases from babel.config.js
📦 Installation
Global Installation
npm install -g react-component-scannerUse with npx (Recommended)
npx react-component-scanner🎯 Quick Start
Basic Usage
Define entry point.
By default, DepGraph opens with entry routes. For example, if your app has 5 tabs, mark them all as entry points:
ComponentName.isEntryRoute = true;
export default ComponentName;Define screens
🤖 Automatic Detection (Recommended) The scanner now automatically detects screens from navigation patterns! No manual marking needed for:
- React Navigation: Components used in
Stack.Screen,Tab.Screen,Drawer.Screen - React Router: Components used in
<Route element={<Component />} />or<Route component={Component} /> - Next.js: Components in
pages/directory orapp/*/page.tsxfiles
📝 Manual Detection (Legacy) To manually mark a component as a screen:
ComponentName.isScreen = true;
ComponentName.isEntryRoute = true;
export default ComponentName;Define custom properties
Custom properties help group similar components. For example, in a car-selling app, multiple card/UI can show car info.
ListingCard.isCarCard = true;
export default ListingCard;Generate dependency graph
npx react-component-scannerCLI Options
npx react-component-scanner [directory] [options]
Options:
-o, --output <file> Output file for component analysis (default: "component-analysis.json")
-d, --dependency-graph <file> Output file for dependency graph (default: "dependency-graph.json")
-e, --extensions <extensions> File extensions to include (default: ".js,.jsx,.ts,.tsx")
-b, --babel-config <path> Path to babel.config.js file (default: "./babel.config.js")
-q, --quiet Suppress verbose output
--no-auto-detect-screens Disable automatic screen detection from navigation patterns
--no-save Don't save results to files (just output stats)
-h, --help Display help for command📊 Output Files
Dependency Graph (dependency-graph.json)
Contains the complete component relationship graph:
{
"totalComponents": 636,
"scanDate": "2024-01-15T10:30:00.000Z",
"collisions": 29,
"dependencyGraph": {
"a1b2c3d4.Button": {
"name": "Button",
"uniqueId": "a1b2c3d4.Button",
"filePath": "src/components/Button/Button.tsx",
"absolutePath": "/project/src/components/Button/Button.tsx",
"type": "function",
"children": ["Text", "e5f6g7h8.TouchableOpacity"],
"childrenWithPaths": [
{
"name": "Text",
"path": null
},
{
"name": "e5f6g7h8.TouchableOpacity",
"path": "/project/src/components/TouchableOpacity/TouchableOpacity.tsx"
}
],
"properties": {
"isScreen": false,
"Remote": true
}
}
}
}🎨 Component Detection
The scanner detects various types of React components:
Function Components
function MyComponent() {
return <div>Hello</div>;
}Arrow Function Components
const MyComponent = () => {
return <div>Hello</div>;
};Class Components
class MyComponent extends React.Component {
render() {
return <div>Hello</div>;
}
}forwardRef Components
const MyComponent = React.forwardRef((props, ref) => {
return <div ref={ref}>Hello</div>;
});memo Components
const MyComponent = React.memo(() => {
return <div>Hello</div>;
});🤖 Automatic Screen Detection
The scanner automatically detects screens from common navigation patterns without requiring manual isScreen = true annotations.
React Navigation Patterns
// Stack Navigator
const Stack = createStackNavigator();
<Stack.Navigator>
<Stack.Screen name="Home" component={HomeScreen} /> // ✅ HomeScreen auto-detected
<Stack.Screen name="Profile" component={ProfileScreen} /> // ✅ ProfileScreen auto-detected
</Stack.Navigator>
// Tab Navigator
const Tab = createBottomTabNavigator();
<Tab.Navigator>
<Tab.Screen name="Main" component={MainScreen} /> // ✅ MainScreen auto-detected
<Tab.Screen name="Settings" component={SettingsScreen} /> // ✅ SettingsScreen auto-detected
</Tab.Navigator>
// Drawer Navigator
const Drawer = createDrawerNavigator();
<Drawer.Navigator>
<Drawer.Screen name="Home" component={HomeScreen} /> // ✅ HomeScreen auto-detected
</Drawer.Navigator>React Router Patterns
// React Router v6
<Routes>
<Route path="/" element={<HomePage />} /> // ✅ HomePage auto-detected
<Route path="/about" element={<AboutPage />} /> // ✅ AboutPage auto-detected
<Route path="/contact" component={ContactPage} /> // ✅ ContactPage auto-detected (v5 style)
</Routes>Next.js File-Based Routing
pages/
index.tsx // ✅ Default export auto-detected as screen
about.tsx // ✅ Default export auto-detected as screen
products/
index.tsx // ✅ Default export auto-detected as screen
[id].tsx // ✅ Default export auto-detected as screen
app/ // Next.js 13+ App Router
page.tsx // ✅ Default export auto-detected as screen
about/
page.tsx // ✅ Default export auto-detected as screen
products/
[id]/
page.tsx // ✅ Default export auto-detected as screenConfiguration
// Disable automatic detection if needed
const results = scanProject({
autoDetectScreens: false // Default: true
});# CLI: Disable automatic detection
npx react-component-scanner --no-auto-detect-screens🔍 Advanced Features
Path Alias Resolution
Automatically reads path aliases from your babel.config.js:
// babel.config.js
module.exports = {
plugins: [
['module-resolver', {
alias: {
'@components': './src/components',
'@screens': './src/screens',
'@utils': './src/utils'
}
}]
]
};Component Properties Detection
Detects custom properties assigned to components:
const MyScreen = () => <ScreenContainer>...</ScreenContainer>;
// These properties are automatically detected
MyScreen.isScreen = true;
MyScreen.Remote = true;
MyScreen.navigate = [
{ screen: 'NextScreen', condition: 'success' },
{ screen: 'ErrorScreen', condition: 'failure' }
];Collision Resolution
Suppose you have multiple components with the same name, the parent will be resolved to have a child with the following preference
- Same-file components (highest priority)
- Import-resolved components (with re-export following)
- First available instance (fallback)
Screen Detection
Automatically identifies screen components:
- Components with
isScreen = trueproperty - Components that use
ScreenContaineras a child
Navigation Flow Analysis
Extracts navigation sequences from component properties:
PaymentScreen.navigate = [
{ screen: 'SuccessScreen', condition: 'payment_success' },
{ screen: 'FailureScreen', condition: 'payment_failed' }
];🛠️ Requirements
- Node.js >= 16.0.0
- React/React Native project with JSX/TSX files
- Optional: babel.config.js with module-resolver plugin for path aliases
Troubleshoot
Wrong component is getting linked as children.
- Please check
Collision Resolutionsection - To debug, try to remove, React.memo, React.forwardRef, any hoc before remove
- Try to have same component import and export name. If component is exported with identifier ShortlistIcon, try to import and use as ShortlistIcon only.
- If issue is still there then try to create a extract children into a separate file
- If you still have issue, please fell free to raise issue on github
Made with ❤️ for the React community
