or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

backend-agent.mdbridge-communication.mddata-hydration.mddevtools-ui.mdfrontend-store.mdhook-system.mdindex.mdperformance-profiling.md
tile.json

tessl/npm-react-devtools-experimental

Experimental rewrite of React DevTools extension for debugging React applications with improved performance and multi-root support

Workspace
tessl
Visibility
Public
Created
Last updated
Describes
npmpkg:npm/react-devtools-experimental@4.0.x

To install, run

npx @tessl/cli install tessl/npm-react-devtools-experimental@4.0.0

index.mddocs/

React DevTools Experimental

React DevTools Experimental is an advanced debugging tool for React applications that provides deep inspection capabilities, performance profiling, and state modification features. This experimental rewrite offers improved performance through message batching, windowing, and reduced bridge traffic compared to legacy DevTools.

Package Information

  • Package Name: react-devtools-experimental
  • Package Type: npm
  • Language: JavaScript with Flow types
  • Installation: This is an experimental development tool, typically used via browser extensions or standalone builds

Core Imports

React DevTools Experimental provides different entry points for different contexts:

Backend Hook Installation:

import { installHook } from "react-devtools-experimental/src/hook";

Backend Initialization:

import { initBackend } from "react-devtools-experimental/src/backend";
import Agent from "react-devtools-experimental/src/backend/agent";

Frontend Initialization:

import { initDevTools } from "react-devtools-experimental/src/devtools";
import Store from "react-devtools-experimental/src/devtools/store";

Bridge Communication:

import Bridge from "react-devtools-experimental/src/bridge";

Basic Usage

Setting up DevTools in a React application:

import { installHook } from "react-devtools-experimental/src/hook";
import { initBackend } from "react-devtools-experimental/src/backend";
import Agent from "react-devtools-experimental/src/backend/agent";
import Bridge from "react-devtools-experimental/src/bridge";

// 1. Install the global hook
const hook = installHook(window);
if (!hook) {
  console.warn("React DevTools hook already installed");
  return;
}

// 2. Create bridge with wall implementation
const wall = {
  listen: (fn) => window.addEventListener('message', fn),
  send: (event, payload) => window.postMessage({ event, payload }, '*')
};
const bridge = new Bridge(wall);

// 3. Initialize backend
const agent = new Agent();
agent.addBridge(bridge);
initBackend(hook, agent, window);

// 4. DevTools is now ready to detect and debug React applications

Basic element inspection:

// Agent methods for element inspection
agent.selectElement({ id: elementId, rendererID: rendererID });
agent.inspectElement({ id: elementId, rendererID: rendererID });
agent.highlightElementInDOM({ id: elementId, rendererID: rendererID });

Architecture

React DevTools Experimental is built around several key architectural patterns:

  • Bridge Communication: Bidirectional message passing between DevTools contexts with automatic batching
  • Hook System: Global hook installation that intercepts React renderer operations
  • Backend Agent: Centralized coordinator that manages renderer interfaces and handles DevTools operations
  • Renderer Interfaces: Version-specific adapters that handle different React renderer implementations
  • Data Hydration: Sophisticated serialization system that handles complex objects and circular references
  • Profiling System: Performance monitoring with interaction tracking and commit analysis
  • Frontend Store: Event-driven state management for DevTools UI with Suspense-based caching

Capabilities

Hook Installation and Management

Core hook system that enables DevTools integration with React applications through global hook installation and renderer detection.

function installHook(target: any): DevToolsHook | null;

interface DevToolsHook {
  listeners: { [key: string]: Array<Function> };
  rendererInterfaces: Map<number, RendererInterface>;
  renderers: Map<number, ReactRenderer>;
  
  emit: (event: string, data: any) => void;
  on: (event: string, handler: Function) => void;
  off: (event: string, handler: Function) => void;
  sub: (event: string, handler: Function) => () => void;
  
  inject: (renderer: ReactRenderer) => number | null;
  getFiberRoots: (rendererID: number) => Set<Object>;
}

Hook System

Bridge Communication

Message passing system with automatic batching for efficient communication between DevTools contexts (extension, content script, injected script).

class Bridge extends EventEmitter {
  constructor(wall: Wall);
  send(event: string, payload: any, transferable?: Array<any>): void;
}

interface Wall {
  listen: (fn: Function) => void;
  send: (event: string, payload: any, transferable?: Array<any>) => void;
}

Bridge Communication

Backend Agent and Control

Central backend coordinator that manages renderer interfaces, handles element inspection, state modification, and profiling operations.

class Agent extends EventEmitter {
  addBridge(bridge: Bridge): void;
  
  inspectElement(params: { id: number, rendererID: number }): void;
  selectElement(params: { id: number, rendererID: number }): void;
  highlightElementInDOM(params: { id: number, rendererID: number }): void;
  
  startInspectingDOM(): void;
  stopInspectingDOM(): void;
  
  overrideContext(params: SetInParams): void;
  overrideHookState(params: OverrideHookParams): void;
  overrideProps(params: SetInParams): void;
  overrideState(params: SetInParams): void;
  
  startProfiling(): void;
  stopProfiling(): void;
}

interface SetInParams {
  id: number;
  path: Array<string | number>;
  rendererID: number;
  value: any;
}

interface OverrideHookParams {
  id: number;
  hookID: number;
  path: Array<string | number>;
  rendererID: number;
  value: any;
}

Backend Agent

Data Hydration and Serialization

Sophisticated data serialization system that handles complex objects, functions, React elements, and circular references for bridge transport.

const meta = {
  name: Symbol('name');
  type: Symbol('type');
  inspected: Symbol('inspected');
  meta: Symbol('meta');
  proto: Symbol('proto');
};

function dehydrate(
  data: Object,
  cleaned: Array<Array<string>>,
  path?: Array<string>,
  level?: number
): string | Object;

function hydrate(data: Object, cleaned: Array<Array<string>>): Object;

function getDisplayNameForReactElement(element: React$Element<any>): string | null;

Data Hydration

Frontend Store and State Management

Event-driven state management for DevTools UI with element tree management, profiling data caching, and Suspense integration.

class Store extends EventEmitter {
  constructor(bridge: Bridge, config?: Config);
  
  get hasProfilingData(): boolean;
  get isProfiling(): boolean;
  get numElements(): number;
  get roots(): $ReadOnlyArray<number>;
  get supportsProfiling(): boolean;
  
  getElementAtIndex(index: number): Element | null;
  getElementIDAtIndex(index: number): number | null;
  getElementByID(id: number): Element | null;
  getIndexOfElementID(id: number): number | null;
  
  startProfiling(): void;
  stopProfiling(): void;
}

interface Config {
  supportsReloadAndProfile?: boolean;
  supportsProfiling?: boolean;
}

Frontend Store

Performance Profiling

Comprehensive performance monitoring system with interaction tracking, commit analysis, and detailed timing data collection.

interface Interaction {
  id: number;
  name: string;
  timestamp: number;
}

interface CommitDetails {
  actualDurations: Array<number>;
  commitIndex: number;
  interactions: Array<Interaction>;
  rootID: number;
}

interface ProfilingSummary {
  commitDurations: Array<number>;
  commitTimes: Array<number>;
  initialTreeBaseDurations: Array<number>;
  interactionCount: number;
  rootID: number;
}

Performance Profiling

DevTools UI Components

React components for rendering the DevTools interface including element tree, profiler, and settings panels.

function DevTools(props: DevToolsProps): React$Element<any>;

interface DevToolsProps {
  bridge: Bridge;
  store: Store;
  browserName?: 'Chrome' | 'Firefox';
  browserTheme?: 'dark' | 'light';
  elementsPortalContainer?: HTMLElement;
  profilerPortalContainer?: HTMLElement;
  settingsPortalContainer?: HTMLElement;
  showTabBar?: boolean;
  viewElementSource?: Function;
}

DevTools UI

Types

Core Communication Types

interface Bridge {
  addListener(type: string, callback: Function): void;
  removeListener(type: string, callback: Function): void;
  send(event: string, payload: any, transferable?: Array<any>): void;
}

interface Wall {
  listen: (fn: Function) => void;
  send: (event: string, payload: any, transferable?: Array<any>) => void;
}

Element and Tree Types

interface Element {
  id: number;
  parentID: number;
  children: Array<number>;
  type: ElementType;
  displayName: string | null;
  key: number | string | null;
  ownerID: number;
  depth: number;
  weight: number;
}

interface InspectedElement {
  id: number;
  canEditHooks: boolean;
  canEditFunctionProps: boolean;
  canViewSource: boolean;
  context: Object | null;
  hooks: Object | null;
  props: Object | null;
  state: Object | null;
  owners: Array<Owner> | null;
  source: Object | null;
}

interface Owner {
  displayName: string;
  id: number;
}

React Integration Types

interface ReactRenderer {
  findHostInstanceByFiber: (fiber: Object) => ?Object;
  findFiberByHostInstance: (hostInstance: Object) => ?Object;
  version: string;
  bundleType: 0 | 1; // PROD | DEV
  overrideHookState?: (fiber: Object, id: number, path: Array<string | number>, value: any) => void;
  overrideProps?: (fiber: Object, path: Array<string | number>, value: any) => void;
  currentDispatcherRef?: { current: null | Object };
}

interface RendererInterface {
  cleanup: () => void;
  inspectElement: (id: number) => InspectedElement | null;
  selectElement: (id: number) => void;
  setInContext: (id: number, path: Array<string | number>, value: any) => void;
  setInHook: (id: number, index: number, path: Array<string | number>, value: any) => void;
  setInProps: (id: number, path: Array<string | number>, value: any) => void;
  setInState: (id: number, path: Array<string | number>, value: any) => void;
  startProfiling: () => void;
  stopProfiling: () => void;
  walkTree: () => void;
}

Constants

const TREE_OPERATION_ADD = 1;
const TREE_OPERATION_REMOVE = 2;
const TREE_OPERATION_RESET_CHILDREN = 3;
const TREE_OPERATION_UPDATE_TREE_BASE_DURATION = 4;

const ElementTypeClass = 1;
const ElementTypeFunction = 2;
const ElementTypeContext = 3;
const ElementTypeForwardRef = 4;
const ElementTypeMemo = 5;
const ElementTypeOtherOrUnknown = 6;
const ElementTypeProfiler = 7;
const ElementTypeRoot = 8;
const ElementTypeSuspense = 9;