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

> Explore the DevTools panel architecture in law-chain-hot/websocket-devtools. Understand key files like devtools.js and panel.jsx, and discover the component structure.

- Repository: [Brian 阿布/websocket-devtools](https://github.com/law-chain-hot/websocket-devtools)
- Tags: architecture
- Published: 2026-03-05

---

**The DevTools panel architecture in `law-chain-hot/websocket-devtools` consists of three distinct layers: an entry registration script in [`src/devtools/devtools.js`](https://github.com/law-chain-hot/websocket-devtools/blob/main/src/devtools/devtools.js), a React-based UI container in [`src/devtools/panel.jsx`](https://github.com/law-chain-hot/websocket-devtools/blob/main/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`](https://github.com/law-chain-hot/websocket-devtools/blob/main/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.

```javascript
// 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`](https://github.com/law-chain-hot/websocket-devtools/blob/main/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`](https://github.com/law-chain-hot/websocket-devtools/blob/main/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.

```javascript
// 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`](https://github.com/law-chain-hot/websocket-devtools/blob/main/src/utils/i18n.js).

## Feature Components Directory

The `src/components/` directory contains modular React components that receive state via props from [`panel.jsx`](https://github.com/law-chain-hot/websocket-devtools/blob/main/panel.jsx) and dispatch actions to the background script using `chrome.runtime.sendMessage()`.

- **ControlPanel** ([`src/components/ControlPanel.jsx`](https://github.com/law-chain-hot/websocket-devtools/blob/main/src/components/ControlPanel.jsx)): Provides toggles for monitoring state and blocking inbound/outbound traffic.
- **WebSocketList** ([`src/components/WebSocketList.jsx`](https://github.com/law-chain-hot/websocket-devtools/blob/main/src/components/WebSocketList.jsx)): Renders the side-by-side connection list and handles manual connection creation through `ManualConnectModal`.
- **MessageDetails** ([`src/components/MessageDetails.jsx`](https://github.com/law-chain-hot/websocket-devtools/blob/main/src/components/MessageDetails.jsx)): Displays message flow with timestamps and provides "Clear" and "Simulate" actions.
- **FloatingSimulate** ([`src/components/FloatingSimulate.jsx`](https://github.com/law-chain-hot/websocket-devtools/blob/main/src/components/FloatingSimulate.jsx)): A draggable overlay for crafting custom messages without navigating away from the current view.
- **SystemEventsTab** ([`src/components/SystemEventsTab.jsx`](https://github.com/law-chain-hot/websocket-devtools/blob/main/src/components/SystemEventsTab.jsx)): Renders internal extension events such as circuit-breaker warnings and connection errors.
- **JsonViewer** ([`src/components/JsonViewer.jsx`](https://github.com/law-chain-hot/websocket-devtools/blob/main/src/components/JsonViewer.jsx)): Pretty-prints JSON payloads with collapsible nodes for readable inspection.

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

```javascript
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:**
- [`src/utils/i18n.js`](https://github.com/law-chain-hot/websocket-devtools/blob/main/src/utils/i18n.js): Manages translation lookup and language change observers for multi-language support.
- [`src/utils/wsHistoryService.js`](https://github.com/law-chain-hot/websocket-devtools/blob/main/src/utils/wsHistoryService.js): Persists connection history to `chrome.storage.local` for session restoration.

**Custom hooks:**
- [`usePanelManager.js`](https://github.com/law-chain-hot/websocket-devtools/blob/main/usePanelManager.js): Handles the DevTools port lifecycle, reconnection logic, and keep-alive health checks.
- [`useNewMessageHighlight.js`](https://github.com/law-chain-hot/websocket-devtools/blob/main/useNewMessageHighlight.js): Provides visual highlighting for newly arrived messages in the UI.
- [`useAutoResize.js`](https://github.com/law-chain-hot/websocket-devtools/blob/main/useAutoResize.js): Dynamically adjusts panel dimensions based on content changes.

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`](https://github.com/law-chain-hot/websocket-devtools/blob/main/main.css) defines global typography and background properties, while individual stylesheets like [`WebSocketList.css`](https://github.com/law-chain-hot/websocket-devtools/blob/main/WebSocketList.css), [`MessageDetails.css`](https://github.com/law-chain-hot/websocket-devtools/blob/main/MessageDetails.css), and [`FloatingSimulate.css`](https://github.com/law-chain-hot/websocket-devtools/blob/main/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`](https://github.com/law-chain-hot/websocket-devtools/blob/main/src/background/background.js). The panel communicates simulation commands using typed messages:

```javascript
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`](https://github.com/law-chain-hot/websocket-devtools/blob/main/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`](https://github.com/law-chain-hot/websocket-devtools/blob/main/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`](https://github.com/law-chain-hot/websocket-devtools/blob/main/i18n.js) and [`usePanelManager.js`](https://github.com/law-chain-hot/websocket-devtools/blob/main/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`](https://github.com/law-chain-hot/websocket-devtools/blob/main/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`](https://github.com/law-chain-hot/websocket-devtools/blob/main/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`](https://github.com/law-chain-hot/websocket-devtools/blob/main/ControlPanel.jsx) for monitoring toggles, [`WebSocketList.jsx`](https://github.com/law-chain-hot/websocket-devtools/blob/main/WebSocketList.jsx) for connection management, and [`FloatingSimulate.jsx`](https://github.com/law-chain-hot/websocket-devtools/blob/main/FloatingSimulate.jsx) for message injection. These components receive state from [`panel.jsx`](https://github.com/law-chain-hot/websocket-devtools/blob/main/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`](https://github.com/law-chain-hot/websocket-devtools/blob/main/src/utils/i18n.js), which provides translation lookup utilities and language change observers. The `LanguageSelector` component in [`src/components/LanguageSelector.jsx`](https://github.com/law-chain-hot/websocket-devtools/blob/main/src/components/LanguageSelector.jsx) allows users to switch languages dynamically, with changes propagated through the React component tree.