react-dev-inspector
Click any element in a running React app to jump straight to its component's source code in your local IDE.
Repository Health
Technical Analysis
react-dev-inspector lets you click any rendered element in a running React app and jump straight to the exact file, line, and column of the component that produced it, turning the browser into a live entry point into your editor. It reads source-location metadata that Babel/SWC already inject into JSX during development (or an optional companion babel-plugin’s fallback), walks the React fiber tree upward to resolve that DOM node to the nearest human-named component, and posts the resulting file/line/column to a small dev-server middleware that shells out to launch-editor on your machine.
The project ships as a pnpm monorepo of framework-specific glue - a Vite plugin, a Webpack config helper, Umi3/Umi4 plugins, and a generic Express-style middleware - so the same <Inspector/> React component can be wired into a wide range of dev-server setups with minimal configuration. A hotkey (Ctrl+Shift+Cmd+C by default) toggles inspect mode, hovering highlights the resolved component with an overlay, and a right-click context menu lets you step through overlapping or nested components at the same screen point before picking one to open in your editor.
What You Get
- An overlay-based hover indicator that highlights the DOM element along with its resolved React component name and source file location.
- A right-click context menu for stepping through overlapping or nested layers when multiple components render on top of each other at the same point.
- Framework plugins and middleware for Vite, Webpack, Umi3, and Umi4, plus a generic Express-based dev-server endpoint that launches your local editor.
- Configurable hotkeys and a controlled/uncontrolled
activeprop so you can wire inspect-mode toggling into your own UI instead of the default keybinding.
Common Use Cases
- Onboarding onto an unfamiliar React codebase by clicking through the rendered UI to locate the component tree responsible for a page.
- Fast bug triage - jumping from a visually broken element straight to its JSX without grepping for class names or text content.
- Design/dev pairing sessions where a non-engineer can point at a UI element and the developer jumps immediately to the underlying code.
- Exploring an open-source project you’re interested in contributing to, without first memorizing its routing and file layout.
Under The Hood
Architecture
The core package centers on a <Inspector/> React component (Inspector.tsx) that composes hooks for interaction state (hotkey toggling, pointer recording, controlled activation), an InspectAgent abstraction (DOMInspectAgent) that owns the activate/deactivate/indicate lifecycle and DOM-to-fiber resolution (utils/fiber.ts, utils/inspect.ts), and a separate web-components package that renders the hover overlay and right-click context panel outside React’s own render tree. Source-location resolution merges two independent strategies in getCodeInfoFromFiber - reading Babel’s injected _debugSource, or reading data-inspector-* attributes set by the companion babel-plugin package - decoupling the runtime component from the compiler transform in use. The actual “open in editor” step is deliberately server-side: the component only computes file/line/column client-side and posts it to a small middleware (@react-dev-inspector/middleware plus @react-dev-inspector/launch-editor-endpoint) that shells out to launch-editor on the dev machine, and each framework package (vite-plugin, umi3-plugin, umi4-plugin) is a thin adapter wiring that middleware and the babel plugin into the framework’s own dev-server hooks.
Tech Stack
TypeScript throughout, organized as a pnpm workspace of eight packages built with per-package tsconfig.esm.json/tsconfig.cjs.json compiled directly via tsc (no bundler) to dual ESM/CJS output. Runtime dependencies are narrow and purposeful: @floating-ui/core for overlay positioning, hotkeys-js for keybinding, lit for the Web Components layer, and picocolors for terminal output in the editor-launch server. Dev tooling is current - Storybook 8 with Vite for isolated component development, ESLint 9 flat config via @antfu/eslint-config, Husky plus lint-staged plus commitlint enforcing Conventional Commits, a GitHub Actions build workflow, and a Next.js/Nextra documentation site under docs/.
Code Quality
Only two of the eight packages (babel-plugin, web-components) carry actual Vitest test files; the core inspector package’s own test script is vitest run --passWithNoTests, meaning it explicitly tolerates shipping without tests for the package most consumers install directly - a real gap given how deep it reaches into React internals. Error handling favors defensive optional-chaining and a silently-swallowed try/catch around the DevTools-hook fiber lookup rather than typed error propagation. Naming is consistent and the public types are precise (CodeInfo, generic InspectAgent<Element>, InspectChainItem), with ESLint and pre-commit hooks enforcing style across the monorepo.
What Makes It Unique
The core technical idea is resolving “click on this DOM node” back to “the source file that rendered it” purely from data React and Babel already produce - the fiber tree plus Babel’s injected _debugSource/__source - rather than requiring bespoke instrumentation, with an optional babel-plugin fallback for compilers that don’t inject that metadata (including a specific workaround for Rspack’s non-standard fileName format). The whole hover/click/context-menu interaction is then generalized behind an InspectAgent interface so the same UI could, in principle, support non-DOM renderers. It’s a narrow, well-executed technical solution rather than a broad novel product.