Experimental rewrite of React DevTools extension for debugging React applications with improved performance and multi-root support
—
Quality
Pending
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
Pending
The risk profile of this skill
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
});
}