DevTools Panel Architecture in law-chain-hot/websocket-devtools: Key Files and Directories

The DevTools panel architecture in law-chain-hot/websocket-devtools consists of three distinct layers: an entry registration script in src/devtools/devtools.js, a React-based UI container in src/devtools/panel.jsx, and modular feature components under src/components/ that handle state management and background script communication.

The law-chain-hot/websocket-devtools repository implements a Chrome/Edge browser extension that injects a custom monitoring interface directly into the browser's DevTools. Understanding the DevTools panel architecture requires tracing how the extension registers its presence, renders the React interface, and coordinates with background scripts to intercept WebSocket traffic.

Entry Point and Panel Registration

The architecture begins with src/devtools/devtools.js, which executes in the DevTools page context and conditionally creates the panel. The script first checks the websocket-proxy-enabled flag in chrome.storage.local via checkExtensionEnabled() before registering the interface.

// src/devtools/devtools.js
checkExtensionEnabled().then((enabled) => {
  if (enabled) {
    chrome.devtools.panels.create(
      "WebSocket DevTools",
      "icons/icon.svg",
      "src/devtools/panel.html",
      /* … */
    );
  }
});

If the extension is enabled, chrome.devtools.panels.create injects src/devtools/panel.html into the DevTools UI. This HTML file serves as the container that loads the bundled React application, ensuring the panel only appears when explicitly activated by the user.

Main Panel UI Implementation

The core rendering logic resides in src/devtools/panel.jsx, which establishes the long-lived communication channel to the background script. Upon mounting, the component opens a named port via chrome.runtime.connect({ name: "devtools" }) and initializes the session with an init message containing the inspected tab's ID.

// src/devtools/panel.jsx
const WebSocketPanel = () => {
  const [isMonitoring, setIsMonitoring] = useState(true);
  const [connectionsMap, setConnectionsMap] = useState(new Map());
  // …
  useEffect(() => {
    const tabId = chrome.devtools.inspectedWindow.tabId;
    setCurrentTabId(tabId);
    const port = chrome.runtime.connect({ name: "devtools" });
    port.postMessage({ type: "init", tabId });
    // …
  }, []);

The component maintains critical state including isMonitoring, connectionsMap, and websocketEvents. It implements a messageListener that distinguishes between websocket-event-batch and websocket-event types, filters traffic by tabId, deduplicates messages via messageId, and enforces the MAX_TOTAL_MESSAGES limit to prevent memory bloat. The UI is wrapped in a MantineProvider for consistent styling and supports internationalization through helpers defined in src/utils/i18n.js.

Feature Components Directory

The src/components/ directory contains modular React components that receive state via props from panel.jsx and dispatch actions to the background script using chrome.runtime.sendMessage().

These components interact with the background script to trigger real network actions. For example, manual WebSocket creation dispatches a create-manual-websocket message:

chrome.runtime.sendMessage({
  type: "create-manual-websocket",
  data: { url: wsUrl, tabId: currentTabId }
});

Utilities and Custom Hooks

The src/utils/ and src/hooks/ directories abstract cross-cutting concerns into reusable modules.

Key utility files:

Custom hooks:

These hooks keep the component layer declarative and facilitate unit testing by isolating side effects.

Styling Architecture

All scoped styles reside under src/styles/ using component-specific CSS files. main.css defines global typography and background properties, while individual stylesheets like WebSocketList.css, MessageDetails.css, and FloatingSimulate.css are imported directly into their corresponding JSX files to maintain encapsulation.

Integration with Background Scripts

While the panel manages UI state, actual WebSocket interception occurs in src/background/background.js. The panel communicates simulation commands using typed messages:

await chrome.runtime.sendMessage({
  type: "simulate-message",
  data: {
    connectionId,
    message,
    direction,          // "send" | "receive"
    tabId: currentTabId,
  },
});

The background script injects these messages into the page context, while the panel adds synthetic events marked with simulated: true to maintain an accurate audit trail.

Summary

  • src/devtools/devtools.js conditionally registers the panel using chrome.devtools.panels.create based on the websocket-proxy-enabled storage flag.
  • src/devtools/panel.jsx serves as the React entry point, managing global state and maintaining a persistent chrome.runtime.connect channel named "devtools".
  • src/components/ houses specialized UI components like ControlPanel, WebSocketList, and FloatingSimulate that handle user interactions and dispatch commands to the background script.
  • src/utils/ and src/hooks/ provide internationalization, history persistence, and lifecycle management through utilities like i18n.js and usePanelManager.js.
  • src/styles/ contains scoped CSS files imported directly by components to ensure style encapsulation.

Frequently Asked Questions

What file is responsible for registering the DevTools panel?

The file src/devtools/devtools.js handles registration. It executes chrome.devtools.panels.create() only after checkExtensionEnabled() confirms the extension is active via the websocket-proxy-enabled storage flag.

How does the panel communicate with the background script?

The panel establishes a long-lived connection using chrome.runtime.connect({ name: "devtools" }) immediately upon mounting in panel.jsx. It sends initialization messages containing the tabId and receives WebSocket events through listeners that filter by message type (websocket-event, websocket-event-batch).

Where are the reusable UI components located?

All React components reside in src/components/, including ControlPanel.jsx for monitoring toggles, WebSocketList.jsx for connection management, and FloatingSimulate.jsx for message injection. These components receive state from panel.jsx and communicate with the background script via chrome.runtime.sendMessage().

How is internationalization handled in the DevTools panel?

Internationalization logic lives in src/utils/i18n.js, which provides translation lookup utilities and language change observers. The LanguageSelector component in src/components/LanguageSelector.jsx allows users to switch languages dynamically, with changes propagated through the React component tree.

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 →