@jsdf/react-devtools-api
v0.0.1
Published
Standalone React DevTools API for querying React component tree
Readme
React DevTools API
A standalone bundle that exposes React DevTools utilities for querying the React component tree. Designed for use with Playwright, Puppeteer, or any tool that can inject JavaScript into a page.
Installation
yarn workspace react-devtools-api buildUsage
Injecting via Playwright
import { chromium } from 'playwright';
import fs from 'fs';
const browser = await chromium.launch();
const page = await browser.newPage();
// Load the bundle
const devtoolsApi = fs.readFileSync(
'path/to/react-devtools-api/dist/react-devtools-api.js',
'utf-8'
);
// Navigate to your React app
await page.goto('http://localhost:3000');
// Inject the DevTools API
await page.evaluate(devtoolsApi);
// Wait for React to be ready
await page.evaluate(() => window.__REACT_DEVTOOLS_API__.waitForReact());
// Now you can query components
const components = await page.evaluate(() => {
const api = window.__REACT_DEVTOOLS_API__;
return api.findComponentsByName('Button');
});
console.log(components);
// [
// { id: 5, rendererID: 1, name: 'Button', path: [...] },
// { id: 12, rendererID: 1, name: 'Button', path: [...] }
// ]API Reference
Finding Components
const api = window.__REACT_DEVTOOLS_API__;
// Find component at a DOM element
api.getComponentForElement(document.querySelector('.my-button'));
// { id: 5, rendererID: 1, name: 'Button', path: [...] }
// Find component by CSS selector
api.getComponentForSelector('.my-button');
// { id: 5, rendererID: 1, name: 'Button', path: [...] }
// Find all components by name (partial match)
api.findComponentsByName('Button');
// [{ id: 5, ... }, { id: 12, ... }]
// Find all components by name (exact match)
api.findComponentsByName('Button', true);
// Find components by regex
api.findComponentsByPattern(/^User/);
// [{ id: 3, name: 'UserList' }, { id: 7, name: 'UserProfile' }]Inspecting Components
// Get detailed component info (props, state, hooks, context)
api.inspectComponent(5);
// {
// id: 5,
// name: 'Button',
// type: 'function',
// props: { onClick: ƒ, children: 'Click me' },
// state: null,
// hooks: [{ name: 'State', value: false }],
// context: null,
// key: null,
// owners: [{ id: 3, displayName: 'App' }]
// }
// Get DOM elements for a component
api.getDOMForComponent(5);
// [<button class="my-button">Click me</button>]
// Get owner chain (parent components)
api.getOwners(5);
// [{ id: 3, displayName: 'App' }, { id: 1, displayName: 'Root' }]
// Get full component tree as string
api.getComponentTree();
// └── App (id: 1)
// ├── Header (id: 2)
// ├── UserList (id: 3)
// │ └── UserItem (id: 4)
// └── Footer (id: 5)Debugging Utilities
// Log component to browser console
api.logComponent(5);
// Highlight a component in the page (2 second overlay)
api.highlightComponent(5);
// Clear all highlights
api.clearHighlights();Status Checks
// Check if DevTools hook is available and React is mounted
api.isAvailable();
// true
// Wait for React to be ready (with timeout)
await api.waitForReact(10000);Advanced
// Get the raw DevTools hook
api.getHook();
// window.__REACT_DEVTOOLS_GLOBAL_HOOK__
// Get the primary renderer interface
api.getRenderer();
// { rendererID: 1, renderer: RendererInterface }
// Get all renderer interfaces (for apps with multiple React roots)
api.getAllRenderers();
// [{ rendererID: 1, renderer: ... }, { rendererID: 2, renderer: ... }]Return Types
ComponentInfo
type ComponentInfo = {
id: number;
rendererID: number;
name: string | null;
path: Array<{
displayName: string | null;
key: string | null;
index: number;
}> | null;
};InspectedComponentInfo
type InspectedComponentInfo = {
id: number;
name: string | null;
type: string;
props: Object | null;
state: Object | null;
hooks: Object | null;
context: Object | null;
key: string | number | null;
owners: Array<{
id: number;
displayName: string | null;
type: string;
}> | null;
};Example: Finding and Clicking a Button
// With Playwright
await page.evaluate((devtoolsApi) => eval(devtoolsApi), devtoolsApiScript);
const buttonInfo = await page.evaluate(() => {
const api = window.__REACT_DEVTOOLS_API__;
const buttons = api.findComponentsByName('SubmitButton', true);
if (buttons.length > 0) {
const dom = api.getDOMForComponent(buttons[0].id);
return { found: true, selector: dom[0].className };
}
return { found: false };
});
if (buttonInfo.found) {
await page.click(`.${buttonInfo.selector}`);
}Notes
- This bundle includes the DevTools hook installer, so it will work even if React DevTools extension is not installed
- The bundle is ~150KB minified
- Works with React 16.8+ (hooks support required for full functionality)
- For production React apps, some inspection features may be limited
