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 DevTools UI system provides React components for rendering the complete DevTools interface including element tree inspection, performance profiler, settings panels, and cross-browser compatibility features.
The primary DevTools component that orchestrates the entire UI experience.
/**
* Main DevTools UI component
* Renders the complete DevTools interface with tabs, panels, and functionality
* @param props - DevTools configuration and dependencies
* @returns React element for DevTools UI
*/
function DevTools(props: DevToolsProps): React$Element<any>;
interface DevToolsProps {
/** Bridge for backend communication */
bridge: Bridge;
/** Store for state management */
store: Store;
/** Browser name for compatibility ('Chrome' | 'Firefox') */
browserName?: BrowserName;
/** Browser theme ('dark' | 'light') */
browserTheme?: BrowserTheme;
/** Container for elements panel portal */
elementsPortalContainer?: HTMLElement;
/** Override default tab selection */
overrideTab?: TabID;
/** Container for profiler panel portal */
profilerPortalContainer?: HTMLElement;
/** Container for settings panel portal */
settingsPortalContainer?: HTMLElement;
/** Whether to show the tab bar */
showTabBar?: boolean;
/** Function to view element source code */
viewElementSource?: Function;
}
type BrowserName = 'Chrome' | 'Firefox';
type BrowserTheme = 'dark' | 'light';
type TabID = 'elements' | 'profiler' | 'settings';Usage Examples:
import { DevTools } from "react-devtools-experimental/src/devtools/views/DevTools";
import Store from "react-devtools-experimental/src/devtools/store";
import Bridge from "react-devtools-experimental/src/bridge";
function App() {
const bridge = new Bridge(wall);
const store = new Store(bridge, { supportsProfiling: true });
return (
<DevTools
bridge={bridge}
store={store}
browserName="Chrome"
browserTheme="dark"
showTabBar={true}
viewElementSource={(id, rendererID) => {
// Open source code in editor
openInEditor(id, rendererID);
}}
/>
);
}React contexts for sharing DevTools dependencies throughout the component tree.
/**
* Context for sharing bridge instance
*/
const BridgeContext: React$Context<Bridge>;
/**
* Context for sharing store instance
*/
const StoreContext: React$Context<Store>;Usage Examples:
import { BridgeContext, StoreContext } from "react-devtools-experimental/src/devtools/views/context";
function DevToolsProvider({ bridge, store, children }) {
return (
<BridgeContext.Provider value={bridge}>
<StoreContext.Provider value={store}>
{children}
</StoreContext.Provider>
</BridgeContext.Provider>
);
}
function ElementInspector() {
const bridge = useContext(BridgeContext);
const store = useContext(StoreContext);
const handleInspect = (elementID) => {
const rendererID = store.getRendererIDForElement(elementID);
bridge.send('inspect-element', { id: elementID, rendererID });
};
return <button onClick={() => handleInspect(42)}>Inspect Element</button>;
}Context and components for managing DevTools user settings and preferences.
/**
* Settings context for user preferences
*/
const SettingsContext: React$Context<SettingsContextValue>;
interface SettingsContextValue {
/** Current display density setting */
displayDensity: DisplayDensity;
/** Function to update display density */
setDisplayDensity: (density: DisplayDensity) => void;
/** Current theme setting */
theme: Theme;
/** Function to update theme */
setTheme: (theme: Theme) => void;
}
type DisplayDensity = 'compact' | 'comfortable';
type Theme = 'auto' | 'light' | 'dark';Usage Examples:
import { SettingsContext } from "react-devtools-experimental/src/devtools/views/Settings/SettingsContext";
function SettingsPanel() {
const { theme, setTheme, displayDensity, setDisplayDensity } = useContext(SettingsContext);
return (
<div>
<div>
<label>Theme:</label>
<select value={theme} onChange={(e) => setTheme(e.target.value)}>
<option value="auto">Auto</option>
<option value="light">Light</option>
<option value="dark">Dark</option>
</select>
</div>
<div>
<label>Display Density:</label>
<select value={displayDensity} onChange={(e) => setDisplayDensity(e.target.value)}>
<option value="compact">Compact</option>
<option value="comfortable">Comfortable</option>
</select>
</div>
</div>
);
}Utility hooks for common DevTools UI patterns and state management.
/**
* Hook for managing localStorage-synchronized state
* @param key - localStorage key to sync with
* @param initialValue - Initial value if no stored value exists
* @returns State value and setter function
*/
function useLocalStorage<T>(key: string, initialValue: T): [T, (value: T) => void];
/**
* Hook for detecting modal dismiss signals (clicks outside, escape key)
* @param modalRef - Ref to modal element
* @returns Whether modal should be dismissed
*/
function useModalDismissSignal(modalRef: { current: HTMLElement | null }): boolean;
/**
* Hook for subscribing to external data sources with automatic cleanup
* @param config - Subscription configuration
* @returns Current subscription value
*/
function useSubscription<Value>(config: SubscriptionConfig<Value>): Value;
interface SubscriptionConfig<Value> {
/** Function to get current value */
getCurrentValue: () => Value;
/** Function to subscribe to changes */
subscribe: (callback: Function) => () => void;
}Usage Examples:
import { useLocalStorage, useModalDismissSignal, useSubscription } from "react-devtools-experimental/src/devtools/views/hooks";
function ElementTree() {
// Persist tree expansion state
const [expandedElements, setExpandedElements] = useLocalStorage('expanded-elements', new Set());
// Subscribe to store updates
const revision = useSubscription({
getCurrentValue: () => store.revision,
subscribe: (callback) => {
store.on('tree-updated', callback);
return () => store.off('tree-updated', callback);
}
});
return (
<div>
Tree revision: {revision}
{/* Tree content */}
</div>
);
}
function Modal({ onClose, children }) {
const modalRef = useRef(null);
const shouldDismiss = useModalDismissSignal(modalRef);
useEffect(() => {
if (shouldDismiss) {
onClose();
}
}, [shouldDismiss, onClose]);
return (
<div className="modal-overlay">
<div ref={modalRef} className="modal">
{children}
</div>
</div>
);
}DevTools uses a tabbed interface for organizing different views and functionality.
/**
* Tab bar component for switching between DevTools panels
*/
function TabBar(props: TabBarProps): React$Element<any>;
interface TabBarProps {
/** Currently active tab ID */
activeTab: TabID;
/** Function called when tab is selected */
onTabSelect: (tabID: TabID) => void;
/** Whether profiling tab should be shown */
showProfilerTab: boolean;
}The elements panel provides the React component tree view and inspection capabilities.
/**
* Elements panel showing React component tree
*/
function Elements(props: ElementsProps): React$Element<any>;
interface ElementsProps {
/** Portal container for rendering */
portalContainer?: HTMLElement;
}
/**
* Individual element node in the tree
*/
function Element(props: ElementProps): React$Element<any>;
interface ElementProps {
/** Element data to render */
element: Element;
/** Current nesting depth */
depth: number;
/** Whether element is selected */
isSelected: boolean;
/** Selection change handler */
onSelect: (elementID: number) => void;
}The profiler panel displays performance analysis and timing data.
/**
* Profiler panel for performance analysis
*/
function Profiler(props: ProfilerProps): React$Element<any>;
interface ProfilerProps {
/** Portal container for rendering */
portalContainer?: HTMLElement;
}
/**
* Profiler controls for starting/stopping sessions
*/
function ProfilerControls(props: ProfilerControlsProps): React$Element<any>;
interface ProfilerControlsProps {
/** Whether profiling is currently active */
isProfiling: boolean;
/** Function to start profiling */
onStart: () => void;
/** Function to stop profiling */
onStop: () => void;
}Components for displaying detailed element inspection information.
/**
* Element inspection details panel
*/
function InspectedElementTree(props: InspectedElementProps): React$Element<any>;
interface InspectedElementProps {
/** Element ID being inspected */
elementID: number;
/** Inspection data */
inspectedElement: InspectedElement;
}
/**
* Component for displaying and editing key-value pairs
*/
function KeyValue(props: KeyValueProps): React$Element<any>;
interface KeyValueProps {
/** Property name */
name: string;
/** Property value */
value: any;
/** Whether value is editable */
isEditable: boolean;
/** Value change handler */
onChange?: (newValue: any) => void;
}Utilities for preparing data for display and clipboard operations.
/**
* Create regular expression from user input string
* Handles special characters and invalid regex patterns
* @param string - User input string
* @returns Valid RegExp object
*/
function createRegExp(string: string): RegExp;
/**
* Get display label for metadata values
* @param data - Data object with metadata
* @returns Human-readable label or null
*/
function getMetaValueLabel(data: Object): string | null;
/**
* Serialize object data for clipboard copying
* @param props - Object to serialize
* @returns Formatted string representation
*/
function serializeDataForCopy(props: Object): string;
/**
* Serialize hooks data for clipboard copying
* @param hooks - Hooks tree to serialize
* @returns Formatted string representation
*/
function serializeHooksForCopy(hooks: HooksTree | null): string;Usage Examples:
import {
createRegExp,
serializeDataForCopy,
serializeHooksForCopy
} from "react-devtools-experimental/src/devtools/views/utils";
// Safe regex creation from user input
function FilterElements({ onFilter }) {
const [filterText, setFilterText] = useState('');
const handleFilter = () => {
const regex = createRegExp(filterText);
onFilter(regex);
};
return (
<div>
<input value={filterText} onChange={(e) => setFilterText(e.target.value)} />
<button onClick={handleFilter}>Filter</button>
</div>
);
}
// Copy element data to clipboard
function CopyButton({ elementData, hooksData }) {
const handleCopy = () => {
const propsString = serializeDataForCopy(elementData.props);
const hooksString = serializeHooksForCopy(hooksData);
const combined = `Props:\n${propsString}\n\nHooks:\n${hooksString}`;
navigator.clipboard.writeText(combined);
};
return <button onClick={handleCopy}>Copy to Clipboard</button>;
}Utilities for handling cross-browser differences and capabilities.
/**
* Get current browser name
* @returns Browser identifier string
*/
function getBrowserName(): BrowserName;
/**
* Get current browser theme preference
* @returns Theme identifier string
*/
function getBrowserTheme(): BrowserTheme;
/**
* Create view source function for browser environment
* @param bridge - Bridge for communication
* @param store - Store for element data
* @returns Function to view element source
*/
function createViewElementSource(bridge: Bridge, store: Store): Function;DevTools components can be rendered into specific DOM containers using React portals.
import { createPortal } from 'react-dom';
function DevToolsApp() {
const elementsContainer = document.getElementById('elements-panel');
const profilerContainer = document.getElementById('profiler-panel');
return (
<>
<TabBar activeTab="elements" onTabSelect={handleTabSelect} />
{elementsContainer && createPortal(
<Elements />,
elementsContainer
)}
{profilerContainer && createPortal(
<Profiler />,
profilerContainer
)}
</>
);
}DevTools components integrate with the store event system for reactive updates.
function ElementTreeView() {
const store = useContext(StoreContext);
const [selectedElementID, setSelectedElementID] = useState(null);
useEffect(() => {
const handleSelection = (elementID) => {
setSelectedElementID(elementID);
};
store.on('element-selected', handleSelection);
return () => store.off('element-selected', handleSelection);
}, [store]);
return (
<div>
{store.roots.map(rootID => (
<ElementSubtree
key={rootID}
elementID={rootID}
selectedElementID={selectedElementID}
onSelect={setSelectedElementID}
/>
))}
</div>
);
}Components automatically adapt to browser theme preferences and user settings.
function ThemedComponent() {
const { theme } = useContext(SettingsContext);
const browserTheme = getBrowserTheme();
const effectiveTheme = theme === 'auto' ? browserTheme : theme;
return (
<div className={`component theme-${effectiveTheme}`}>
{/* Component content */}
</div>
);
}DevTools components include comprehensive accessibility support.
function AccessibleTree() {
return (
<div
role="tree"
aria-label="React component tree"
onKeyDown={handleKeyboardNavigation}
>
{elements.map(element => (
<div
key={element.id}
role="treeitem"
aria-expanded={element.children.length > 0 ? expanded : undefined}
aria-level={element.depth + 1}
tabIndex={selected ? 0 : -1}
>
{element.displayName}
</div>
))}
</div>
);
}