How a Chrome Extension DevTools Panel Integrates with Chrome's Built-in DevTools

A Chrome extension adds a custom DevTools panel by declaring a devtools_page in the manifest, which calls chrome.devtools.panels.create() to register a new tab inside Chrome's native DevTools interface.

The jonghakseo/chrome-extension-boilerplate-react-vite repository demonstrates a complete implementation of how a devtools panel integrates with Chrome's built-in DevTools using a React-based architecture. This integration relies on three coordinated components: the manifest declaration, the DevTools page script, and the panel UI application.

The Three-Core Architecture

The integration follows a specific pipeline defined by Chrome's extension API. Each component serves a distinct role in bridging the extension with Chrome's native DevTools environment.

Component Role Source File
Manifest Declares the devtools_page entry point chrome-extension/manifest.ts (line 72)
DevTools Page Executes chrome.devtools.panels.create() pages/devtools/src/index.ts
Panel UI Renders the React application inside the new panel pages/devtools-panel/src/index.tsx and Panel.tsx

Step 1: Declaring the DevTools Page in manifest.ts

Chrome requires a devtools_page entry in the extension manifest to initialize any DevTools-related functionality. In chrome-extension/manifest.ts, line 72 declares this entry point:

devtools_page: 'devtools/index.html',

This declaration instructs Chrome to load devtools/index.html whenever the user opens Chrome DevTools. The HTML file includes a script tag that loads the compiled output from pages/devtools/src/index.ts, establishing the bridge between the extension and Chrome's built-in DevTools.

Step 2: Creating the Panel via chrome.devtools.panels.create()

The script at pages/devtools/src/index.ts runs within the DevTools context—not the background script or popup context. It uses the chrome.devtools.panels API to register a new panel:

// pages/devtools/src/index.ts
try {
  console.log("Edit 'pages/devtools/src/index.ts' and save to reload.");
  // Register a new panel named “Dev Tools” using our custom UI page.
  chrome.devtools.panels.create(
    'Dev Tools',                // Panel title
    '/icon-34.png',            // Optional icon
    '/devtools-panel/index.html' // HTML page rendered inside the panel
  );
} catch (e) {
  console.error(e);
}

The chrome.devtools.panels.create() method accepts three parameters: the display title for the tab, an optional icon path, and the URL of the HTML page to render within the panel. This call registers the extension's panel as a first-class tab within Chrome's native DevTools interface, alongside Elements, Console, and Network.

Step 3: Rendering the React UI Inside the Panel

Once Chrome creates the panel, it loads /devtools-panel/index.html, which bootstraps the React application. The entry point at pages/devtools-panel/src/index.tsx mounts the component tree:

// pages/devtools-panel/src/index.tsx
import '@src/index.css';
import Panel from '@src/Panel';
import { createRoot } from 'react-dom/client';

const init = () => {
  const appContainer = document.querySelector('#app-container');
  if (!appContainer) throw new Error('Can not find #app-container');

  const root = createRoot(appContainer);
  root.render(<Panel />);
};

init();

The Panel.tsx component implements the actual UI, utilizing shared utilities for theming and Chrome API access:

// pages/devtools-panel/src/Panel.tsx
import '@src/Panel.css';
import { t } from '@extension/i18n';
import { PROJECT_URL_OBJECT, useStorage, withErrorBoundary, withSuspense } from '@extension/shared';
import { exampleThemeStorage } from '@extension/storage';
import { cn, ErrorDisplay, LoadingSpinner } from '@extension/ui';
import type { ComponentPropsWithoutRef } from 'react';

const Panel = () => {
  const { isLight } = useStorage(exampleThemeStorage);
  const logo = isLight ? 'devtools-panel/logo_horizontal.svg' : 'devtools-panel/logo_horizontal_dark.svg';
  const goGithubSite = () => chrome.tabs.create(PROJECT_URL_OBJECT);

  return (
    <div className={cn('App', isLight ? 'bg-slate-50' : 'bg-gray-800')}>
      <header className={cn('App-header', isLight ? 'text-gray-900' : 'text-gray-100')}>
        <button onClick={goGithubSite}>
          <img src={chrome.runtime.getURL(logo)} className="App-logo" alt="logo" />
        </button>
        <p>Edit <code>pages/devtools-panel/src/Panel.tsx</code></p>
        <ToggleButton onClick={exampleThemeStorage.toggle}>{t('toggleTheme')}</ToggleButton>
      </header>
    </div>
  );
};

export default withErrorBoundary(withSuspense(Panel, <LoadingSpinner />), ErrorDisplay);

This architecture allows the devtools panel to integrate seamlessly with Chrome's built-in DevTools while maintaining full access to extension APIs like chrome.runtime.getURL and chrome.tabs.create.

Communication and Shared Utilities

The integration relies on shared packages to maintain consistency across the extension. The exampleThemeStorage utility, defined in the shared packages, synchronizes theme state between the panel and other extension components. The PROJECT_URL_OBJECT constant from packages/shared/const.ts provides standardized URL references.

Error handling and loading states are implemented via higher-order components withErrorBoundary and withSuspense from @extension/ui, ensuring the panel remains stable even when asynchronous operations fail.

Summary

  • Manifest declaration: The devtools_page entry in chrome-extension/manifest.ts initializes the DevTools integration.
  • Panel registration: The pages/devtools/src/index.ts script calls chrome.devtools.panels.create() to add a custom tab to Chrome's DevTools.
  • UI rendering: The pages/devtools-panel/src/index.tsx entry point mounts a React application inside the panel using standard Chrome extension APIs.
  • Shared architecture: Utilities from @extension/shared and @extension/ui provide theming, error handling, and cross-extension communication.

Frequently Asked Questions

What is the purpose of the devtools_page in the manifest?

The devtools_page serves as the entry point that Chrome loads whenever a user opens the browser's DevTools. According to the chrome-extension-boilerplate-react-vite source code, this page runs in a special DevTools context and executes the script that calls chrome.devtools.panels.create() to register custom panels.

How does chrome.devtools.panels.create() work?

The chrome.devtools.panels.create() method registers a new panel tab inside Chrome's native DevTools interface. As implemented in pages/devtools/src/index.ts, it accepts three parameters: the display title for the tab, an optional icon path, and the URL of the HTML page to render within the panel frame.

Can the DevTools panel communicate with the background script?

Yes, the DevTools panel operates within the extension's context and can access all Chrome extension APIs. The Panel.tsx component demonstrates this by using chrome.tabs.create() to open external links and chrome.runtime.getURL() to load local assets. It can also use chrome.runtime.sendMessage() to communicate with background scripts or other extension components.

What UI framework does the devtools panel use?

The devtools panel uses React with TypeScript, bundled by Vite. The entry point at pages/devtools-panel/src/index.tsx creates a React root and renders the Panel component, which utilizes Tailwind CSS for styling and shared packages from @extension/ui for error boundaries and suspense handling.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →