The Backend Agent is the central coordinator in the DevTools backend that manages renderer interfaces, handles bridge communication, and orchestrates all debugging operations including element inspection, state modification, and performance profiling.
Main backend coordinator that extends EventEmitter and manages all DevTools operations.
/**
* Central backend agent that coordinates DevTools operations
* Manages renderer interfaces and handles bridge communication
*/
class Agent extends EventEmitter {
/**
* Create a new agent instance
*/
constructor();
/**
* Add bridge for communication with DevTools frontend
* @param bridge - Bridge instance for message passing
*/
addBridge(bridge: Bridge): void;
/**
* Set renderer interface for specific renderer
* @param rendererID - Unique renderer identifier
* @param rendererInterface - Interface to React renderer
*/
setRendererInterface(rendererID: number, rendererInterface: RendererInterface): void;
/**
* Shut down agent and clean up resources
*/
shutdown(): void;
}Usage Examples:
import Agent from "react-devtools-experimental/src/backend/agent";
import Bridge from "react-devtools-experimental/src/bridge";
// Create agent
const agent = new Agent();
// Set up bridge communication
const bridge = new Bridge(wall);
agent.addBridge(bridge);
// Listen for agent events
agent.on('element-inspected', (data) => {
console.log('Element inspection complete:', data);
});
// Clean up when done
agent.shutdown();Methods for inspecting React elements and components in the application.
/**
* Inspect a specific React element and return detailed information
* @param params - Element identification parameters
*/
inspectElement(params: InspectSelectParams): void;
/**
* Select an element in the DevTools tree
* @param params - Element identification parameters
*/
selectElement(params: InspectSelectParams): void;
/**
* Highlight an element in the DOM for visual identification
* @param params - Element identification with display name
*/
highlightElementInDOM(params: HighlightParams): void;
interface InspectSelectParams {
id: number;
rendererID: number;
}
interface HighlightParams {
displayName?: string;
id: number;
rendererID: number;
}Usage Examples:
// Inspect specific element
agent.inspectElement({
id: 42,
rendererID: 1
});
// Select element in tree
agent.selectElement({
id: 42,
rendererID: 1
});
// Highlight element with custom display name
agent.highlightElementInDOM({
id: 42,
rendererID: 1,
displayName: 'MyComponent'
});Methods for entering and exiting DOM inspection mode where users can click elements to inspect them.
/**
* Enter DOM inspection mode
* Allows clicking on DOM elements to inspect corresponding React components
*/
startInspectingDOM(): void;
/**
* Exit DOM inspection mode
* Returns to normal DevTools operation
*/
stopInspectingDOM(): void;
/**
* Get React element ID for a DOM node
* @param node - DOM node to find React element for
* @returns React element ID or null if not found
*/
getIDForNode(node: Object): number | null;Usage Examples:
// Enter inspection mode
agent.startInspectingDOM();
// User clicks on DOM element, get corresponding React element
const domNode = document.querySelector('.my-component');
const elementID = agent.getIDForNode(domNode);
if (elementID) {
agent.inspectElement({ id: elementID, rendererID: 1 });
}
// Exit inspection mode
agent.stopInspectingDOM();Methods for modifying React component state, props, context, and hooks in real-time.
/**
* Override component context values
* @param params - Context modification parameters
*/
overrideContext(params: SetInParams): void;
/**
* Override React hook state values
* @param params - Hook state modification parameters
*/
overrideHookState(params: OverrideHookParams): void;
/**
* Override component props values
* @param params - Props modification parameters
*/
overrideProps(params: SetInParams): void;
/**
* Override component state values
* @param params - State modification parameters
*/
overrideState(params: SetInParams): 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;
}Usage Examples:
// Modify component props
agent.overrideProps({
id: 42,
path: ['user', 'name'],
rendererID: 1,
value: 'New Name'
});
// Modify component state
agent.overrideState({
id: 42,
path: ['isVisible'],
rendererID: 1,
value: true
});
// Modify hook state (e.g., useState)
agent.overrideHookState({
id: 42,
hookID: 0, // First hook
path: [], // Root value
rendererID: 1,
value: 'New Hook Value'
});
// Modify context values
agent.overrideContext({
id: 42,
path: ['theme'],
rendererID: 1,
value: 'dark'
});Methods for controlling React performance profiling sessions.
/**
* Start performance profiling session
* Begins collecting timing and interaction data
*/
startProfiling(): void;
/**
* Stop performance profiling session
* Ends data collection and prepares results
*/
stopProfiling(): void;
/**
* Get current profiling status
* Returns whether profiling is currently active
*/
getProfilingStatus(): void;
/**
* Get profiling summary for specific root
* @param params - Root identification parameters
*/
getProfilingSummary(params: ProfilingParams): void;
/**
* Reload application and start profiling
* Useful for capturing initial render performance
*/
reloadAndProfile(): void;
interface ProfilingParams {
rendererID: number;
rootID: number;
}Usage Examples:
// Start profiling session
agent.startProfiling();
// Perform actions to profile...
// (user interactions, state changes, etc.)
// Stop profiling and get results
agent.stopProfiling();
// Get profiling summary for specific root
agent.getProfilingSummary({
rendererID: 1,
rootID: 1
});
// Profile initial page load
agent.reloadAndProfile();Methods for analyzing React commit performance and interaction data.
/**
* Get detailed information about a specific commit
* @param params - Commit identification parameters
*/
getCommitDetails(params: CommitParams): void;
/**
* Get interaction data for a specific root
* @param params - Root identification parameters
*/
getInteractions(params: ProfilingParams): void;
interface CommitParams {
commitIndex: number;
rendererID: number;
rootID: number;
}Usage Examples:
// Get details for specific commit
agent.getCommitDetails({
commitIndex: 5,
rendererID: 1,
rootID: 1
});
// Get all interactions for root
agent.getInteractions({
rendererID: 1,
rootID: 1
});Methods for viewing React component source code.
/**
* Request to view element source code
* Opens source in external editor or DevTools source tab
* @param params - Element identification parameters
*/
viewElementSource(params: InspectSelectParams): void;Usage Examples:
// View source code for component
agent.viewElementSource({
id: 42,
rendererID: 1
});Internal method for processing React hook operations from the global hook.
/**
* Handle operations from React DevTools hook
* Internal method called by hook system
* @param operations - Serialized operations data
*/
onHookOperations(operations: Uint32Array): void;Typical pattern for initializing the backend agent system:
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. Create agent
const agent = new Agent();
// 2. Set up bridge communication
const bridge = new Bridge(wall);
agent.addBridge(bridge);
// 3. Initialize backend with hook
const hook = window.__REACT_DEVTOOLS_GLOBAL_HOOK__;
initBackend(hook, agent, window);
// 4. Agent is now ready to handle DevTools operationsThe agent manages multiple renderer interfaces for different React versions:
// Agent automatically receives renderer interfaces
hook.on('renderer-attached', ({ id, rendererInterface }) => {
agent.setRendererInterface(id, rendererInterface);
// Agent can now operate on this renderer
console.log(`Renderer ${id} ready for debugging`);
});The agent orchestrates complex event flows between frontend and backend:
// Frontend requests element inspection
bridge.on('inspect-element', ({ id, rendererID }) => {
agent.inspectElement({ id, rendererID });
});
// Agent processes request and sends response
agent.on('element-inspected', (elementData) => {
bridge.send('element-inspected', elementData);
});
// Frontend receives and displays inspection results
bridge.on('element-inspected', (data) => {
displayElementInspection(data);
});The agent includes comprehensive error handling:
agent.on('error', (error) => {
console.error('Agent error:', error);
// Send error to frontend
bridge.send('backend-error', {
message: error.message,
stack: error.stack,
timestamp: Date.now()
});
});
// Handle renderer errors
agent.on('renderer-error', ({ rendererID, error }) => {
console.error(`Renderer ${rendererID} error:`, error);
// Attempt to recover or disable renderer
if (error.fatal) {
agent.setRendererInterface(rendererID, null);
}
});Proper cleanup ensures no memory leaks:
// Listen for shutdown events
window.addEventListener('beforeunload', () => {
agent.shutdown();
});
// Manual shutdown
agent.shutdown();
// Agent cleans up:
// - Removes all event listeners
// - Closes bridge connections
// - Clears renderer interfaces
// - Stops profiling sessions
// - Releases references