{"id":20837181,"url":"https://github.com/aidenybai/react-scan","last_synced_at":"2025-09-09T21:23:29.609Z","repository":{"id":262817700,"uuid":"851321035","full_name":"aidenybai/react-scan","owner":"aidenybai","description":"Scan for React performance issues and eliminate slow renders in your app","archived":false,"fork":false,"pushed_at":"2025-04-27T02:02:40.000Z","size":43502,"stargazers_count":17933,"open_issues_count":123,"forks_count":274,"subscribers_count":34,"default_branch":"main","last_synced_at":"2025-04-27T23:42:43.997Z","etag":null,"topics":["javascript","react","react-dom","react-scan","rendering"],"latest_commit_sha":null,"homepage":"https://react-scan.com","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/aidenybai.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":".github/CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2024-09-02T21:52:12.000Z","updated_at":"2025-04-27T20:46:01.000Z","dependencies_parsed_at":null,"dependency_job_id":"308ad427-2151-4ea9-bdcc-0196b76a8823","html_url":"https://github.com/aidenybai/react-scan","commit_stats":null,"previous_names":["aidenybai/react-scan"],"tags_count":14,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aidenybai%2Freact-scan","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aidenybai%2Freact-scan/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aidenybai%2Freact-scan/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aidenybai%2Freact-scan/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/aidenybai","download_url":"https://codeload.github.com/aidenybai/react-scan/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":252527647,"owners_count":21762738,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["javascript","react","react-dom","react-scan","rendering"],"created_at":"2024-11-18T01:01:17.763Z","updated_at":"2025-09-09T21:23:29.596Z","avatar_url":"https://github.com/aidenybai.png","language":"TypeScript","funding_links":[],"categories":["TypeScript","Web Frontend","javascript","react","Projects","🌐 Web Development - Frontend","Uncategorized"],"sub_categories":["React \u0026 UI Libraries","Uncategorized"],"readme":"# \u003cimg src=\"https://github.com/aidenybai/react-scan/blob/main/.github/assets/logo.svg\" width=\"30\" height=\"30\" align=\"center\" /\u003e React Scan\n\nReact Scan automatically detects performance issues in your React app.\n\nPreviously, tools like:\n\n- [React Devtools](https://legacy.reactjs.org/blog/2018/09/10/introducing-the-react-profiler.html) can feel too complex and janky\n- [Why Did You Render?](https://github.com/welldone-software/why-did-you-render) lacked simple visual cues\n\nReact Scan attempts to solve these problems:\n\n- It requires no code changes – just drop it in\n- It highlights exactly the components you need to optimize\n- No more having to use flame graphs when profiling\n- Always accessible through a toolbar on page\n\n### Try it in 5 seconds\n\u003cpre\u003e\nnpx react-scan airbnb.com\n\u003c/pre\u003e\n\nor on your local website\n\u003cpre\u003e\nnpx react-scan localhost:3000\n\u003c/pre\u003e\n\n\u003e all installation options below\n\n\n\n### [**Try out a demo! →**](https://react-scan.million.dev)\n\u003cimg\n  src=\"https://github.com/user-attachments/assets/c21b3afd-c7e8-458a-a760-9a027be7dc02\"\n  alt=\"React Scan in action\"\n  width=\"600\"\n/\u003e\n\n## Install\n\n### Package managers\n\n```bash\nnpm i react-scan\n```\n\n```bash\npnpm add react-scan\n```\n\n```bash\nbun add react-scan\n```\n\n```bash\nyarn add react-scan\n```\n\n## Usage\n\n- [Script Tag](https://github.com/aidenybai/react-scan/blob/main/docs/installation/cdn.md)\n- [NextJS App Router](https://github.com/aidenybai/react-scan/blob/main/docs/installation/next-js-app-router.md)\n- [NextJS Page Router](https://github.com/aidenybai/react-scan/blob/main/docs/installation/next-js-page-router.md)\n- [Vite](https://github.com/aidenybai/react-scan/blob/main/docs/installation/vite.md)\n- [Create React App](https://github.com/aidenybai/react-scan/blob/main/docs/installation/create-react-app.md)\n- [Parcel](https://github.com/aidenybai/react-scan/blob/main/docs/installation/parcel.md)\n- [Remix](https://github.com/aidenybai/react-scan/blob/main/docs/installation/remix.md)\n- [React Router](https://github.com/aidenybai/react-scan/blob/main/docs/installation/react-router.md)\n- [Astro](https://github.com/aidenybai/react-scan/blob/main/docs/installation/astro.md)\n- [TanStack Start](https://github.com/aidenybai/react-scan/blob/main/docs/installation/tanstack-start.md)\n- [Rsbuild](https://github.com/aidenybai/react-scan/blob/main/docs/installation/rsbuild.md)\n\n### CLI\n\nIf you want to run react scan on any URL (including localhost) from the cli, you can run:\n\n```bash\nnpx react-scan@latest http://localhost:3000\n# you can technically scan ANY website on the web:\n# npx react-scan@latest https://react.dev\n```\n\nYou can add it to your existing dev process as well. Here's an example for Next.js:\n\n```json\n{\n  \"scripts\": {\n    \"dev\": \"next dev\",\n    \"scan\": \"next dev \u0026 npx react-scan@latest localhost:3000\"\n  }\n}\n```\n\n### Browser Extension\n\nIf you want to install the extension, follow the guide [here](https://github.com/aidenybai/react-scan/blob/main/BROWSER_EXTENSION_GUIDE.md).\n\n### React Native\n\nSee [discussion](https://github.com/aidenybai/react-scan/pull/23)\n\n\n## After Setup\n\n\u003cdetails\u003e\n\u003csummary\u003e\u003ccode\u003eHow to use/feature descriptions\u003c/code\u003e\u003c/summary\u003e\n  \n### Toolbar\nAll react scan features are exposed through the toolbar that you will see in the bottom right corner of your page:\n\n\u003cimg width=\"220\" alt=\"image\" src=\"https://github.com/user-attachments/assets/20b83531-7e06-48c2-92d4-07f398dcace4\" /\u003e\n\n\u003e You can drag this toolbar to any corner of the page\n\n### Render Outlines\nBy default, react scan will show outlines over components when they render.\n\u003e interact with your page to try it out!\n\nIf you want to turn the outlines off, you can use the toggle in the toolbar to turn them off. This will persist across page loads and will only re-enable when you toggle it back on:\n\n\u003cimg width=\"211\" alt=\"Pasted image 20250629130910\" src=\"https://github.com/user-attachments/assets/d88852a1-0270-4d53-ad71-55a9f4b6c9ea\" /\u003e\n\n\n###  Why did my component render\nIf you want to find out why a component re-rendered, you can click the icon at the very left of the toolbar, and then click on the component you want to inspect\n\u003cimg width=\"1079\" alt=\"Pasted image 20250629131113\" src=\"https://github.com/user-attachments/assets/56d926f7-07f4-40cb-a025-14f48b81de81\" /\u003e\nAnytime the component renders, React Scan will tell you what props, state, or context changed during the last render. If those values didn't change, and your component was wrapped in `React.memo`, it would not of rendered.\n\nTo the right of the of the \"Why did this component render\" view, you will see the component tree of your app. When a component re-renders, the count will be updated in the tree. You can click on any item in the tree to see why it rendered.\n\n\n### Profiling slowdowns in your app\n\nRe-render outlines are good for getting a high level overview of what's slowing down your app, and the \"Why did this render\" inspector is great when you know which component you want to debug. But, what if you don't know which components are causing your app to slowdown?\n\nReact Scan's profiler, accessible through the notification bell in the toolbar:\n\n\u003cimg width=\"524\" alt=\"image\" src=\"https://github.com/user-attachments/assets/435c1c42-e1a1-4478-9e40-d0ef52f00bce\" /\u003e\n\n\nis an always on profiler that alerts you when there is an FPS drop or slow interaction (click, type). Every slowdown and interaction has an easy to understand profile associated with it.\n\n\nhttps://github.com/user-attachments/assets/c7d72e57-d805-4f21-944b-2347b72b0304\n\n\n\nThe profile has 3 parts:\n#### Ranked\n\nThis ranks how long it took to render your components. Every component instance that came from the same component will have its render time added together- if you render 1000 `ListItem`'s , and they each take 1s to render, we will say `ListItem` took 1000s to render )\n\n\u003cimg width=\"438\" alt=\"image\" src=\"https://github.com/user-attachments/assets/9e8f4496-e975-4d4f-9519-4b5c653c4f94\" /\u003e\n  \nIf you click on any bar, it will tell you what caused those components to re-render:\n\n\u003cimg width=\"424\" alt=\"Pasted image 20250629132303\" src=\"https://github.com/user-attachments/assets/79915809-64ae-4c32-abc8-89d83e775618\" /\u003e\n\nThis table is telling you that there were 4 instances of this component rendered, and all 4 of them had their `close`, `style`, and `hide` props change. If those didn't change, and the component was `React.memo`'d, they would not have rendered\n\nIf you click the arrow on the side of each bar, it will show you the ancestors of the components that rendered that component, along with how long it took to render that ancestor. This is great for giving context to understand what component you're looking at:\n\n\u003cimg width=\"425\" alt=\"image\" src=\"https://github.com/user-attachments/assets/7ad8f7f6-1514-4852-988a-63efb79c5cbf\" /\u003e\n\nIf you hover your mouse over a bar, all instances of that component will be outlined in purple over the page:\n\n\u003cimg width=\"1197\" alt=\"image\" src=\"https://github.com/user-attachments/assets/b1c6e9f4-97a7-4405-90f4-537938c7a2cc\" /\u003e\n\n\n#### Overview\nThe overview gives you a high level summary of what time was spent on during the slowdown or interaction.\n\nThis breaks down if the time spent was on renders, react hooks (or other javascript not from react), or the browser spending time to update the dom and draw the next frame\n\nThis is great to find out if React was really the problem, or if you should be optimizing other things, like CSS:\n\u003cimg width=\"431\" alt=\"Pasted image 20250629132429\" src=\"https://github.com/user-attachments/assets/9552a802-eea4-4aa6-b46c-79318d4916ea\" /\u003e\n\n#### Prompts\nThe prompts section gives you 3 different kind of prompts that you can pass to an LLM based on what your goal is. These prompts automatically includes data about the profile:\n\n\u003cimg width=\"438\" alt=\"Pasted image 20250629132608\" src=\"https://github.com/user-attachments/assets/20be5326-5355-4a6e-b049-746ed93a05ce\" /\u003e\n\n\n\n#### Misc\nIf you want to hear a sound every time a slowdown is collected, you can turn on audio alerts in this section  \n\u003cimg src=\"https://github.com/user-attachments/assets/7c6fa96d-56be-427a-bb09-078df4223378\" width=\"400\" /\u003e\n\n### Hiding the toolbar\n\nThe React Scan toolbar can be distracting when you're not using it. To hide the toolbar, you can drag/throw it into the side of the page.  \n\n\u003cvideo src=\"https://github.com/user-attachments/assets/358bbc63-d2e0-4e31-af85-2cece1f331b8\" width=\"300\" controls\u003e\u003c/video\u003e\n\n\n\nThe toolbar will stay collapsed into the side of the page until you drag it back out. This will persist across page load\n\n\n\u003c/details\u003e\n\n## API Reference\n\n\u003cdetails\u003e\n\u003csummary\u003e\u003ccode\u003eOptions\u003c/code\u003e\u003c/summary\u003e\n\n\u003cbr /\u003e\n\n```tsx\nexport interface Options {\n  /**\n   * Enable/disable scanning\n   *\n   * Please use the recommended way:\n   * enabled: process.env.NODE_ENV === 'development',\n   *\n   * @default true\n   */\n  enabled?: boolean;\n\n  /**\n   * Force React Scan to run in production (not recommended)\n   *\n   * @default false\n   */\n  dangerouslyForceRunInProduction?: boolean;\n  /**\n   * Log renders to the console\n   *\n   * WARNING: This can add significant overhead when the app re-renders frequently\n   *\n   * @default false\n   */\n  log?: boolean;\n\n  /**\n   * Show toolbar bar\n   *\n   * If you set this to true, and set {@link enabled} to false, the toolbar will still show, but scanning will be disabled.\n   *\n   * @default true\n   */\n  showToolbar?: boolean;\n\n  /**\n   * Animation speed\n   *\n   * @default \"fast\"\n   */\n  animationSpeed?: \"slow\" | \"fast\" | \"off\";\n\n  /**\n   * Track unnecessary renders, and mark their outlines gray when detected\n   *\n   * An unnecessary render is defined as the component re-rendering with no change to the component's\n   * corresponding dom subtree\n   *\n   *  @default false\n   *  @warning tracking unnecessary renders can add meaningful overhead to react-scan\n   */\n  trackUnnecessaryRenders?: boolean;\n\n  onCommitStart?: () =\u003e void;\n  onRender?: (fiber: Fiber, renders: Array\u003cRender\u003e) =\u003e void;\n  onCommitFinish?: () =\u003e void;\n  onPaintStart?: (outlines: Array\u003cOutline\u003e) =\u003e void;\n  onPaintFinish?: (outlines: Array\u003cOutline\u003e) =\u003e void;\n}\n```\n\n\u003c/details\u003e\n\n- `scan(options: Options)`: Imperative API to start scanning\n- `useScan(options: Options)`: Hook API to start scanning\n- `setOptions(options: Options): void`: Set options at runtime\n- `getOptions()`: Get the current options\n- `onRender(Component, onRender: (fiber: Fiber, render: Render) =\u003e void)`: Hook into a specific component's renders\n\n## Why React Scan?\n\nReact can be tricky to optimize.\n\nThe issue is that component props are compared by reference, not value. This is intentional – this way rendering can be cheap to run.\n\nHowever, this makes it easy to accidentally cause unnecessary renders, making the app slow. Even in production apps, with hundreds of engineers, can't fully optimize their apps (see [GitHub](https://github.com/aidenybai/react-scan/blob/main/.github/assets/github.mp4), [Twitter](https://github.com/aidenybai/react-scan/blob/main/.github/assets/twitter.mp4), and [Instagram](https://github.com/aidenybai/react-scan/blob/main/.github/assets/instagram.mp4)).\n\nThis often comes down to props that update in reference, like callbacks or object values. For example, the `onClick` function and `style` object are re-created on every render, causing `ExpensiveComponent` to re-render and slow down the app, even if `ExpensiveComponent` was wrapped in React.memo:\n\n```jsx\n\u003cExpensiveComponent onClick={() =\u003e alert(\"hi\")} style={{ color: \"purple\" }} /\u003e\n```\n\nReact Scan helps you identify these issues by automatically detecting and highlighting renders that cause performance issues. Now, instead of guessing, you can see exactly which components you need to fix.\n\n\u003e Want monitor issues in production? Check out [React Scan Monitoring](https://react-scan.com/monitoring)!\n\n\n## Resources \u0026 Contributing Back\n\nWant to try it out? Check the [our demo](https://react-scan.million.dev).\n\nLooking to contribute back? Check the [Contributing Guide](https://github.com/aidenybai/react-scan/blob/main/CONTRIBUTING.md) out.\n\nWant to talk to the community? Hop in our [Discord](https://discord.gg/X9yFbcV2rF) and share your ideas and what you've build with React Scan.\n\nFind a bug? Head over to our [issue tracker](https://github.com/aidenybai/react-scan/issues) and we'll do our best to help. We love pull requests, too!\n\nWe expect all contributors to abide by the terms of our [Code of Conduct](https://github.com/aidenybai/react-scan/blob/main/.github/CODE_OF_CONDUCT.md).\n\n[**→ Start contributing on GitHub**](https://github.com/aidenybai/react-scan/blob/main/CONTRIBUTING.md)\n\n## Acknowledgments\n\nReact Scan takes inspiration from the following projects:\n\n- [React Devtools](https://react.dev/learn/react-developer-tools) for the initial idea of [highlighting renders](https://medium.com/dev-proto/highlight-react-components-updates-1b2832f2ce48). We chose to diverge from this to provide a [better developer experience](https://x.com/aidenybai/status/1857122670929969551)\n- [Million Lint](https://million.dev) for scanning and linting approaches\n- [Why Did You Render?](https://github.com/welldone-software/why-did-you-render) for the concept of hijacking internals to detect unnecessary renders caused by \"unstable\" props\n\n## License\n\nReact Scan is [MIT-licensed](LICENSE) open-source software by Aiden Bai, [Million Software, Inc.](https://million.dev), and [contributors](https://github.com/aidenybai/react-scan/graphs/contributors).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Faidenybai%2Freact-scan","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Faidenybai%2Freact-scan","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Faidenybai%2Freact-scan/lists"}