The React DevTools hook system provides the foundational integration layer that enables DevTools to connect with React applications. It installs a global hook that intercepts React renderer operations and provides the communication bridge between React internals and DevTools.
Installs the global React DevTools hook in a target environment (typically window).
/**
* Installs the React DevTools global hook in the target environment
* @param target - Target object (usually window) to install hook on
* @returns DevToolsHook instance or null if already installed
*/
function installHook(target: any): DevToolsHook | null;Usage Examples:
import { installHook } from "react-devtools-experimental/src/hook";
// Install hook in browser environment
const hook = installHook(window);
if (hook) {
console.log("DevTools hook installed successfully");
} else {
console.log("Hook already exists");
}
// Hook is available globally
const existingHook = window.__REACT_DEVTOOLS_GLOBAL_HOOK__;The global hook object that manages React renderer connections and provides event communication.
interface DevToolsHook {
/** Event listeners registry */
listeners: { [key: string]: Array<Function> };
/** Renderer interface instances */
rendererInterfaces: Map<number, RendererInterface>;
/** React renderer instances */
renderers: Map<number, ReactRenderer>;
/** Emit events to registered listeners */
emit: (event: string, data: any) => void;
/** Register event listener */
on: (event: string, handler: Function) => void;
/** Remove event listener */
off: (event: string, handler: Function) => void;
/** Subscribe to events with automatic cleanup */
sub: (event: string, handler: Function) => () => void;
/** Register React renderer and return unique ID */
inject: (renderer: ReactRenderer) => number | null;
/** Get fiber roots for specific renderer */
getFiberRoots: (rendererID: number) => Set<Object>;
/** Dead code elimination check for production builds */
checkDCE: (fn: Function) => void;
/** React fiber unmount callback */
onCommitFiberUnmount: (rendererID: number, fiber: Object) => void;
/** React fiber root commit callback */
onCommitFiberRoot: (rendererID: number, root: Object) => void;
/** Legacy support flag for React 16+ */
supportsFiber: boolean;
/** Reference to DevTools Agent instance */
reactDevtoolsAgent?: Object | null;
}The hook provides an event system for communication between React renderers and DevTools.
/**
* Register an event listener
* @param event - Event name to listen for
* @param handler - Function to call when event occurs
*/
on(event: string, handler: Function): void;
/**
* Remove an event listener
* @param event - Event name
* @param handler - Function to remove
*/
off(event: string, handler: Function): void;
/**
* Subscribe to an event with automatic cleanup
* @param event - Event name to subscribe to
* @param handler - Function to call when event occurs
* @returns Cleanup function to remove the subscription
*/
sub(event: string, handler: Function): () => void;
/**
* Emit an event to all registered listeners
* @param event - Event name to emit
* @param data - Data to pass to listeners
*/
emit(event: string, data: any): void;Usage Examples:
// Subscribe to renderer registration
const unsubscribe = hook.sub('renderer', ({ id, renderer }) => {
console.log(`Renderer ${id} registered:`, renderer);
});
// Emit custom events
hook.emit('custom-event', { message: 'Hello DevTools' });
// Clean up subscription
unsubscribe();The hook manages React renderer instances and provides access to their fiber roots.
/**
* Register a React renderer with the hook
* @param renderer - React renderer instance to register
* @returns Unique renderer ID or null if registration fails
*/
inject(renderer: ReactRenderer): number | null;
/**
* Get fiber roots for a specific renderer
* @param rendererID - ID of the renderer
* @returns Set of fiber root objects
*/
getFiberRoots(rendererID: number): Set<Object>;Usage Examples:
// Register renderer
const rendererID = hook.inject(ReactDOM._internalRenderer);
console.log(`Renderer registered with ID: ${rendererID}`);
// Access fiber roots
const fiberRoots = hook.getFiberRoots(rendererID);
fiberRoots.forEach(root => {
console.log('Fiber root:', root);
});Methods called by React during fiber operations to notify DevTools of changes.
/**
* Called by React when a fiber is unmounted
* @param rendererID - ID of the renderer
* @param fiber - Fiber being unmounted
*/
onCommitFiberUnmount(rendererID: number, fiber: Object): void;
/**
* Called by React when a fiber root commits
* @param rendererID - ID of the renderer
* @param root - Fiber root being committed
*/
onCommitFiberRoot(rendererID: number, root: Object): void;
/**
* Checks for dead code elimination in production builds
* @param fn - Function to check for DCE
*/
checkDCE(fn: Function): void;Internal utilities for detecting React build types and configurations.
/**
* Detect React build type from renderer
* @param renderer - React renderer instance
* @returns Build type ('development', 'production', or 'deadcode')
*/
function detectReactBuildType(renderer: ReactRenderer): string;Usage Examples:
// Build type detection happens automatically during renderer injection
hook.on('renderer', ({ renderer, reactBuildType }) => {
console.log(`React build type: ${reactBuildType}`);
if (reactBuildType === 'development') {
console.log('Development mode detected');
} else if (reactBuildType === 'deadcode') {
console.warn('Dead code elimination not properly configured');
}
});The typical hook integration pattern follows these steps:
import { installHook } from "react-devtools-experimental/src/hook";
// 1. Install hook before React loads
const hook = installHook(window);
// 2. Set up event listeners for renderer detection
hook.on('renderer', ({ id, renderer, reactBuildType }) => {
console.log(`Detected React renderer ${id}:`, renderer);
console.log(`Build type: ${reactBuildType}`);
// 3. Initialize DevTools backend for this renderer
setupDevToolsForRenderer(id, renderer);
});
// 4. Hook will automatically detect renderers as they initialize
// React renderer injection happens automatically when React loads
function setupDevToolsForRenderer(rendererID, renderer) {
// Connect DevTools backend to this renderer
const rendererInterface = attachToRenderer(rendererID, renderer);
// Register interface with hook
hook.rendererInterfaces.set(rendererID, rendererInterface);
// Notify that renderer is ready
hook.emit('renderer-attached', {
id: rendererID,
renderer,
rendererInterface
});
}