Skip to main content

Installation

The fastest way to get started is with the automatic setup command:
1

Run the init command

The CLI will detect your framework and configure everything automatically:
npx react-scan@latest init
The init command:
  • Detects your framework (Next.js, Vite, Remix, etc.)
  • Detects your package manager (npm, pnpm, yarn, bun)
  • Installs react-scan as a dev dependency
  • Adds the necessary script tags to your project
  • Shows a preview of changes before applying them
2

Start your dev server

Run your development server as usual:
npm run dev
3

Open your app

Navigate to your app in the browser. You’ll see the React Scan toolbar in the bottom-right corner.React Scan toolbar

First Steps

Once React Scan is running, try these interactions:
Click the toolbar icon to enable/disable render detection. When enabled, components will be highlighted as they re-render:
  • Red outline: Slow render (potential performance issue)
  • Yellow outline: Fast render
  • Gray outline: Unnecessary render (no DOM changes)
Click on any highlighted component to inspect it. You’ll see:
  • Component name and render count
  • What changed (props, state, or context)
  • Render duration
  • Component tree hierarchy
The toolbar shows:
  • FPS meter: Current frames per second
  • Slowdown count: Number of performance issues detected
  • Settings: Configure animation speed, logging, and more

Using the API

For programmatic control, use the scan() function:
import Script from "next/script";

export default function RootLayout({ children }) {
  return (
    <html>
      <head>
        <Script
          src="//unpkg.com/react-scan/dist/auto.global.js"
          crossOrigin="anonymous"
          strategy="beforeInteractive"
        />
      </head>
      <body>{children}</body>
    </html>
  );
}

Configuration Options

Customize React Scan’s behavior with these options:
interface Options {
  /**
   * Enable/disable scanning
   * @default true
   */
  enabled?: boolean;

  /**
   * Force React Scan to run in production (not recommended)
   * @default false
   */
  dangerouslyForceRunInProduction?: boolean;

  /**
   * Log renders to the console
   * @default false
   */
  log?: boolean;

  /**
   * Show toolbar bar
   * @default true
   */
  showToolbar?: boolean;

  /**
   * Animation speed
   * @default "fast"
   */
  animationSpeed?: 'slow' | 'fast' | 'off';

  /**
   * Track unnecessary renders (adds overhead)
   * @default false
   */
  trackUnnecessaryRenders?: boolean;

  /**
   * Show FPS meter
   * @default true
   */
  showFPS?: boolean;

  /**
   * Show notification count
   * @default true
   */
  showNotificationCount?: boolean;

  // Lifecycle hooks
  onCommitStart?: () => void;
  onRender?: (fiber: Fiber, renders: Array<Render>) => void;
  onCommitFinish?: () => void;
}
For most projects, the default options work great. Only customize if you have specific needs.

Example: Detecting Issues

Here’s a simple example showing how React Scan helps identify performance problems:
function TodoList({ items }) {
  return (
    <div>
      {items.map(item => (
        // ⚠️ New function on every render!
        <TodoItem
          key={item.id}
          item={item}
          onToggle={() => toggleItem(item.id)}
          style={{ color: 'purple' }} // ⚠️ New object!
        />
      ))}
    </div>
  );
}
With React Scan running, you’ll immediately see TodoItem components highlighted in red when using the problematic version. After optimization, the unnecessary renders disappear.

Runtime Control

Change options at runtime using the API:
import { scan, setOptions, getOptions } from 'react-scan';

// Start scanning
scan();

// Update options later
setOptions({ 
  animationSpeed: 'slow',
  log: true 
});

// Get current options
const currentOptions = getOptions();
console.log(currentOptions.value);

Monitor Specific Components

Track renders for specific components:
import { onRender } from 'react-scan';

function ExpensiveComponent() {
  // Component logic
}

// Log whenever this component renders
onRender(ExpensiveComponent, (fiber, renders) => {
  console.log('ExpensiveComponent rendered:', {
    count: renders.length,
    changes: renders.map(r => r.changes),
  });
});

Next Steps

Now that React Scan is running, explore these topics:

Understanding Renders

Learn what causes renders and how to prevent unnecessary ones

Performance Optimization

Best practices for React performance

Toolbar Guide

Master the React Scan toolbar features

API Reference

Complete API documentation

Troubleshooting

Make sure React Scan is loaded before React runs. The script must be in the <head> before any React code.Check the console for this error:
[React Scan] Failed to load. Must import React Scan before React runs.
  1. Verify scanning is enabled (toolbar icon should be active)
  2. Ensure you’re in development mode (React Scan disables in production by default)
  3. Check that components are actually re-rendering by interacting with your app
React Scan is designed for development use. If you notice performance issues:
  • Disable log option (adds significant overhead)
  • Set animationSpeed to 'off'
  • Disable trackUnnecessaryRenders
  • Use enabled: false when not actively debugging
Install type definitions:
npm install -D react-scan
Types are included in the package. If you’re using the global script tag, add:
declare global {
  interface Window {
    reactScan: (options?: Options) => void;
  }
}
Need more help? Join our Discord community or open an issue on GitHub.

Build docs developers (and LLMs) love