The DevTools backend is the bridge between the React reconciler and the DevTools frontend UI. It consists of a global hook for discovery, a renderer-specific interface for tree traversal, and an agent that coordinates communication via a serialized protocol.
__REACT_DEVTOOLS_GLOBAL_HOOK__)React DevTools discovers React instances by looking for a global object named __REACT_DEVTOOLS_GLOBAL_HOOK__ on the window or global scope. This hook acts as a central registry where renderers (Fiber, Legacy, or Flight) "inject" themselves.
When a React renderer (e.g., react-dom) initializes, it checks for the existence of this hook. If found, it calls hook.inject(renderer) packages/react-devtools-shared/src/hook.js75 The hook is responsible for managing multiple renderers and assigning them unique RendererIDs packages/react-devtools-shared/src/backend/types.js85
console to append component stacks to errors and warnings packages/react-devtools-shared/src/hook.js53-54 This is controlled by the appendComponentStack setting packages/react-devtools-shared/src/__tests__/console-test.js62Sources: packages/react-devtools-shared/src/hook.js1-170 packages/react-devtools-shared/src/backend/types.js123-193 packages/react-devtools-shared/src/__tests__/console-test.js62
DevTools supports multiple React architectures through a RendererInterface. This interface decouples the high-level DevTools logic from the specific internal structures of the Fiber reconciler, the legacy Stack reconciler, or Flight (Server Components).
Fiber nodes to build the component tree and tracks updates via commit hooks packages/react-devtools-shared/src/backend/fiber/renderer.js199-213mountComponent and receiveComponent in renderer.Reconciler packages/react-devtools-shared/src/backend/legacy/renderer.js220-230The RendererInterface translates React's internal state into a flat array of integers known as "Operations". This array is sent over the bridge to the frontend to minimize serialization overhead.
| Operation Constant | Purpose |
|---|---|
TREE_OPERATION_ADD | Adds a new element to the DevTools tree packages/react-devtools-shared/src/constants.js80 |
TREE_OPERATION_REMOVE | Removes an element from the tree packages/react-devtools-shared/src/constants.js81 |
TREE_OPERATION_REORDER_CHILDREN | Updates the order of siblings packages/react-devtools-shared/src/constants.js82 |
TREE_OPERATION_UPDATE_TREE_BASE_DURATION | Reports profiling duration for a subtree packages/react-devtools-shared/src/constants.js85 |
SUSPENSE_TREE_OPERATION_ADD | Adds a suspense-related node to the tree packages/react-devtools-shared/src/constants.js87 |
TREE_OPERATION_APPLIED_ACTIVITY_SLICE_CHANGE | Updates activity/offscreen state packages/react-devtools-shared/src/constants.js86 |
This diagram illustrates how the Agent coordinates between the DevToolsHook and the RendererInterface.
Sources: packages/react-devtools-shared/src/backend/fiber/renderer.js75-96 packages/react-devtools-shared/src/backend/agent.js265-275 packages/react-devtools-shared/src/hook.js75 packages/react-devtools-shared/src/attachRenderer.js packages/react-devtools-shared/src/constants.js80-91
The Agent is the primary orchestrator of the backend. It listens for commands from the frontend (via the Bridge) and delegates them to the appropriate RendererInterface.
The Agent handles high-level features that span across renderers:
Highlighter tool to highlight native host instances packages/react-devtools-shared/src/backend/agent.js17-18profilingHooks packages/react-devtools-shared/src/backend/agent.js338-345inspectElement packages/react-devtools-shared/src/backend/agent.js78-84 The Agent also handles merging inspection data for multiple roots, particularly for ElementTypeRoot packages/react-devtools-shared/src/backend/agent.js210-263The Bridge is an EventEmitter that abstracts the underlying transport layer (e.g., window.postMessage in browser extensions or WebSockets in standalone) packages/react-devtools-shared/src/bridge.js10-15
It enforces a BRIDGE_PROTOCOL versioning system to ensure compatibility between the frontend and backend builds packages/react-devtools-shared/src/bridge.js47-70 The current protocol version is managed by currentBridgeProtocol packages/react-devtools-shared/src/bridge.js72-73
The following diagram traces the flow when a user clicks a component in the DevTools UI.
Sources: packages/react-devtools-shared/src/backend/agent.js78-84 packages/react-devtools-shared/src/bridge.js162-167 packages/react-devtools-shared/src/devtools/store.js147-172 packages/react-devtools-shared/src/backend/fiber/renderer.js97 packages/react-devtools-shared/src/backend/agent.js210-263
Tree updates are transmitted as a stream of integers to maximize performance. The RendererInterface builds this buffer during a React commit.
To avoid sending repetitive strings (like component names or HOC labels), the backend maintains a string table.
utfEncodeString packages/react-devtools-shared/src/utils.js198-221A typical operations payload follows this sequence as processed by printOperationsArray packages/react-devtools-shared/src/utils.js223-230:
rendererID (int) packages/react-devtools-shared/src/utils.js225rootID (int) packages/react-devtools-shared/src/utils.js226TREE_OPERATION_ADD) packages/react-devtools-shared/src/constants.js80Sources: packages/react-devtools-shared/src/utils.js223-245 packages/react-devtools-shared/src/backend/fiber/renderer.js75-96 packages/react-devtools-shared/src/constants.js80-91 packages/react-devtools-shared/src/frontend/types.js30-44
Refresh this wiki