# How to Integrate React Developer Tools into a React Chrome Extension

> Learn how to integrate React Developer Tools into your React Chrome extension for seamless debugging. Follow simple steps to connect the DevTools client and launch the standalone backend.

- Repository: [Meta/react](https://github.com/facebook/react)
- Tags: how-to-guide
- Published: 2026-02-16

---

**Inject the DevTools client script from `http://localhost:8097` as the first script tag in your extension's HTML before importing `react-dom`, then run `npx react-devtools` to launch the standalone backend that connects to your React chrome extension via WebSocket port 8097.**

When building a React chrome extension, debugging component hierarchies and state changes requires the same visibility you'd expect from a standard web app. According to the facebook/react source code, the official React Developer Tools can connect to any JavaScript context—including extension popups, options pages, and content scripts—by running the DevTools backend in a service worker and injecting the client script before React initializes.

## How React Developer Tools Connects to Chrome Extensions

The official React Developer Tools extension uses a background service worker that opens a WebSocket connection on **port 8097**, as defined in [`packages/react-devtools-extensions/chrome/manifest.json`](https://github.com/facebook/react/blob/main/packages/react-devtools-extensions/chrome/manifest.json). When the extension is loaded in Chrome, this service worker automatically starts and listens for the React runtime inside any page that loads the DevTools client script.

This architecture allows the DevTools backend to bridge the isolated JavaScript context of a Chrome extension with the standalone DevTools UI, enabling component tree inspection, props monitoring, and state debugging regardless of whether your React code runs in a popup, options page, or content script.

## Step-by-Step Integration Guide

### Step 1: Install the Official React Developer Tools Extension

Install the React Developer Tools from the Chrome Web Store, or build it locally from the facebook/react repository using `yarn build:chrome` from the repository root, which outputs to `packages/react-devtools-extensions/chrome/build`.

### Step 2: Inject the DevTools Client Before React DOM

For any page you want to inspect—such as the extension's popup, options page, or content-script-generated UI—you must load the client script **before** `react-dom` initializes. According to [`packages/react-devtools/README.md`](https://github.com/facebook/react/blob/main/packages/react-devtools/README.md) (lines 75-84), add the following as the **first** script in your page's `<head>`:

```html
<!doctype html>
<html lang="en">
  <head>
    <!-- Load the DevTools client first -->
    <script src="http://localhost:8097"></script>
    <!-- Then your normal app scripts -->
    <script type="module" src="src/index.js"></script>
  </head>
  <body>
    <div id="root"></div>
  </body>
</html>

```

Alternatively, if you prefer ES modules, you can import the client as the very first line in your entry point (lines 86-90 of the README):

```javascript
import 'react-devtools';
import React from 'react';
import { createRoot } from 'react-dom/client';

```

### Step 3: Launch the Standalone DevTools Backend

With the client script injected, start the standalone DevTools UI using the package's CLI:

```bash
npx react-devtools

```

This launches a separate DevTools window that automatically connects to your extension's page over port 8097, displaying the component tree, props, and state exactly as it would for a standard web application.

### Step 4: Configure File URL Access for Local Development

When developing with local `file://` URLs, you must enable **Allow access to file URLs** for the React Developer Tools extension in `chrome://extensions` (as documented in lines 94-99 of the README). Without this permission, the extension cannot inject the backend script into pages loaded from the local filesystem.

## Complete Code Examples

### Manifest Configuration

The React Developer Tools extension itself uses Manifest V3 with a background service worker, as shown in [`packages/react-devtools-extensions/chrome/manifest.json`](https://github.com/facebook/react/blob/main/packages/react-devtools-extensions/chrome/manifest.json):

```json
{
  "manifest_version": 3,
  "name": "React Developer Tools",
  "description": "Adds React debugging tools to the Chrome Developer Tools.",
  "version": "7.0.1",
  "devtools_page": "main.html",
  "background": { "service_worker": "build/background.js" },
  "permissions": ["scripting", "storage", "tabs"]
}

```

### Extension Popup HTML Setup

For your own extension's popup, ensure the DevTools client precedes your application code:

```html
<!doctype html>
<html lang="en">
<head>
  <!-- React DevTools client – MUST be first -->
  <script src="http://localhost:8097"></script>
  <meta charset="utf-8" />
  <title>My React Extension</title>
</head>
<body>
  <div id="root"></div>
  <script type="module" src="src/popup.js"></script>
</body>
</html>

```

### React Entry Point

Your JavaScript entry point should initialize React after the DevTools client has established its global hook:

```javascript
import React from 'react';
import { createRoot } from 'react-dom/client';
import App from './App';

// Ensure the DevTools client has already been injected before this import
const container = document.getElementById('root');
const root = createRoot(container);
root.render(<App />);

```

## Key Source Files in the React Repository

| File | Purpose | Link |
|------|---------|------|
| [`packages/react-devtools-extensions/chrome/manifest.json`](https://github.com/facebook/react/blob/main/packages/react-devtools-extensions/chrome/manifest.json) | Chrome-extension manifest that registers the DevTools background worker and content script. | [View on GitHub](https://github.com/facebook/react/blob/main/packages/react-devtools-extensions/chrome/manifest.json) |
| [`packages/react-devtools-extensions/README.md`](https://github.com/facebook/react/blob/main/packages/react-devtools-extensions/README.md) | Instructions for building and testing the DevTools extensions locally. | [View on GitHub](https://github.com/facebook/react/blob/main/packages/react-devtools-extensions/README.md) |
| [`packages/react-devtools/README.md`](https://github.com/facebook/react/blob/main/packages/react-devtools/README.md) | How to run the stand-alone DevTools client (`react-devtools` CLI) and inject it into a page. | [View on GitHub](https://github.com/facebook/react/blob/main/packages/react-devtools/README.md) |
| [`packages/react-devtools-extensions/chrome/README.md`](https://github.com/facebook/react/blob/main/packages/react-devtools-extensions/chrome/README.md) | Details about the Chrome-specific source location and build steps. | [View on GitHub](https://github.com/facebook/react/blob/main/packages/react-devtools-extensions/chrome/README.md) |

## Troubleshooting Common Issues

### Connection Refused on Port 8097

If the standalone DevTools window cannot connect, verify that the background service worker from the official extension is running and listening on **port 8097**. Check `chrome://extensions` to ensure the React Developer Tools extension is enabled and has not been blocked by a firewall or corporate policy.

### DevTools Not Detecting React

The most common cause is incorrect script loading order. The DevTools client must execute before `react-dom` initializes to establish its global hook on the `window` object. As implemented in `packages/react-devtools`, if the client loads after the renderer, the backend cannot intercept the React internal fiber tree, resulting in the "React not detected" message.

### File URL Access Requirements

When developing with local `file://` URLs, you must enable **Allow access to file URLs** for the React Developer Tools extension in `chrome://extensions` (as documented in lines 94-99 of the README). Without this permission, the extension cannot inject the backend script into pages loaded from the local filesystem.

## Summary

- **React Developer Tools** connects to Chrome extensions via a background service worker listening on **port 8097**, as defined in [`packages/react-devtools-extensions/chrome/manifest.json`](https://github.com/facebook/react/blob/main/packages/react-devtools-extensions/chrome/manifest.json).
- To enable debugging, inject the client script (`http://localhost:8097`) as the **first script** in your extension's HTML, or use `import 'react-devtools'` as the first ES module import.
- Launch the standalone backend with **`npx react-devtools`** to open the debugging UI.
- Enable **Allow access to file URLs** in `chrome://extensions` when developing with local `file://` protocols.

## Frequently Asked Questions

### Can I use React Developer Tools with Manifest V3 Chrome extensions?

Yes. The official React Developer Tools extension uses Manifest V3 with a background service worker, as shown in [`packages/react-devtools-extensions/chrome/manifest.json`](https://github.com/facebook/react/blob/main/packages/react-devtools-extensions/chrome/manifest.json). The service worker listens on port 8097 and functions identically to Manifest V2 background pages, ensuring full compatibility with modern React chrome extensions.

### Do I need to install React Developer Tools from the Chrome Web Store to debug my extension?

No. While installing the official extension enables the background service worker automatically, you can run the standalone DevTools backend locally using **`npx react-devtools`** without installing the store extension. However, you must still inject the client script into your extension pages for the connection to establish.

### Why must the DevTools client script load before React DOM?

The client must establish a global hook on the `window` object before React initializes its renderer. As implemented in `packages/react-devtools`, if the client loads after `react-dom`, the backend cannot intercept the React internal fiber tree, resulting in a "React not detected" error in the DevTools panel.

### Can I debug content scripts with React Developer Tools?

Yes, but content scripts run in an isolated JavaScript context separate from the main page. You must programmatically inject the DevTools client script (`http://localhost:8097`) into the content script's execution context before React loads, using the `scripting` API or by bundling the client code as the first import in your content script's entry point.