Skip to main content

Installation

npm install vite-plugin-react-scan
pnpm add vite-plugin-react-scan
yarn add vite-plugin-react-scan

Usage

Add the plugin to your vite.config.ts:
vite.config.ts
import { defineConfig } from 'vite';
import react from '@vitejs/plugin-react';
import reactScan from 'vite-plugin-react-scan';

export default defineConfig({
  plugins: [
    react(),
    reactScan({
      enable: process.env.NODE_ENV === 'development',
    }),
  ],
});

Plugin Options

enable
boolean
default:"process.env.NODE_ENV === 'development'"
Enable or disable the plugin.
reactScan({
  enable: true,
})
scanOptions
Options
Custom React Scan options to pass to the scan() function.See Configuration Options for all available options.
reactScan({
  scanOptions: {
    enabled: true,
    showToolbar: true,
    log: false,
    animationSpeed: 'fast',
  },
})
debug
boolean
default:"false"
Enable debug logging for the plugin.
reactScan({
  debug: true,
})
This will log:
  • Plugin initialization
  • File transformations
  • Script injection
  • Build events
autoDisplayNames
boolean
default:"false"
Automatically add display names to React components.
reactScan({
  autoDisplayNames: true,
})
This helps with component identification in the React Scan UI.
Enabling this option will add Babel transformations to your build process, which may increase build time slightly.

How It Works

Development Mode

In development, the plugin:
  1. Excludes react-scan from Vite’s dependency optimization
  2. Injects a script tag that imports and initializes React Scan
  3. Optionally transforms JSX files to add component display names
Example injected script:
<script type="module">
  import { scan } from '/@id/react-scan';
  (async () => {
    try {
      scan({ enabled: true });
    } catch (error) {
      console.error('[vite-plugin-react-scan] Scan failed:', error);
    }
  })();
</script>

Production Mode

In production builds, the plugin:
  1. Bundles react-scan as a static asset
  2. Injects the script at the beginning of your HTML
  3. Initializes React Scan with your configured options
React Scan is disabled by default in production. Only use dangerouslyForceRunInProduction for debugging purposes.

Configuration Examples

Basic Setup

vite.config.ts
import { defineConfig } from 'vite';
import react from '@vitejs/plugin-react';
import reactScan from 'vite-plugin-react-scan';

export default defineConfig({
  plugins: [
    react(),
    reactScan(),
  ],
});

Custom Options

vite.config.ts
import { defineConfig } from 'vite';
import react from '@vitejs/plugin-react';
import reactScan from 'vite-plugin-react-scan';

export default defineConfig({
  plugins: [
    react(),
    reactScan({
      enable: process.env.NODE_ENV === 'development',
      scanOptions: {
        enabled: true,
        showToolbar: true,
        log: false,
        animationSpeed: 'fast',
        trackUnnecessaryRenders: true,
      },
    }),
  ],
});

With Display Names

vite.config.ts
import { defineConfig } from 'vite';
import react from '@vitejs/plugin-react';
import reactScan from 'vite-plugin-react-scan';

export default defineConfig({
  plugins: [
    react(),
    reactScan({
      autoDisplayNames: true,
    }),
  ],
});

Environment-Based Configuration

vite.config.ts
import { defineConfig } from 'vite';
import react from '@vitejs/plugin-react';
import reactScan from 'vite-plugin-react-scan';

export default defineConfig(({ mode }) => ({
  plugins: [
    react(),
    reactScan({
      enable: mode === 'development',
      scanOptions: {
        log: mode === 'development' && process.env.VERBOSE === 'true',
        trackUnnecessaryRenders: process.env.TRACK_RENDERS === 'true',
      },
    }),
  ],
}));

Debug Mode

vite.config.ts
import { defineConfig } from 'vite';
import react from '@vitejs/plugin-react';
import reactScan from 'vite-plugin-react-scan';

export default defineConfig({
  plugins: [
    react(),
    reactScan({
      debug: true,
      scanOptions: {
        _debug: 'verbose',
      },
    }),
  ],
});

Troubleshooting

React Scan not appearing

  1. Verify the plugin is loaded:
    // vite.config.ts should have:
    plugins: [react(), reactScan()]
    
  2. Check browser console for errors
  3. Enable debug mode:
    reactScan({ debug: true })
    

Plugin conflicts

Ensure react() plugin comes before reactScan():
plugins: [
  react(),      // ✅ First
  reactScan(),  // ✅ Second
]

Build errors

If you encounter build errors with autoDisplayNames:
reactScan({
  autoDisplayNames: false, // Disable this option
})

See Also

Build docs developers (and LLMs) love