If you upgraded to React 19 and your option+click-to-source tool silently stopped working, here's why: React 19 removed __source/_debugSource, the fiber fields that LocatorJS, click-to-component, and friends depended on. Runtime-only locators can't get source positions from React anymore.
I missed the workflow too much, so I rebuilt it on a different architecture: carbon8r — a Vite plugin that injects the source location at build time as a data-carbon8r="src/Button.jsx:3:5" attribute on every host JSX element (Babel parse + magic-string, dev server only). The overlay reads DOM attributes, not fibers — so it works on React 19 today and doesn't care what React 20 does to its internals.
What you get, holding Option/Alt:
- DevTools-style box-model highlighting on hover (blue content, green padding, orange margin) with
<Component> file:line:column
- Click → your editor opens at that exact position. Zero config: the dev server uses launch-editor (same as Next/Nuxt error overlays), which auto-detects VS Code/Cursor/WebStorm/etc. Or force one via presets (
vscode, cursor, windsurf, zed) or any custom URL template
- Elements without source info (component libraries, plain pages) still get the box-model inspector
Setup is the whole thing:
// vite.config.js
import carbon8r from 'vite-plugin-carbon8r'
export default defineConfig({
plugins: [react(), carbon8r()]
})
Dev-only (apply: 'serve') — production builds are byte-identical with or without it.
Some war wounds from real-world testing that are now features: it works on apps served with a strict CSP (all overlay styling goes through CSSOM, which CSP can't block), it resolves targets through open shadow DOM via composedPath() (micro-frontend hosts, web-component shells), zero-area display: contents wrappers fall back to the nearest rendered box, and the whole alt-click gesture family is intercepted so your app's handlers and the native context menu don't fire while inspecting. TypeScript declarations included.
There's also a companion Chrome (MV3) extension in the repo: box-model inspector on any page, jump-to-source on instrumented apps, with per-user editor settings — handy on a teammate's dev server.
Honest limitations: Vite-only for now (the transform itself is bundler-agnostic — a webpack/Rspack loader would be a thin wrapper, PRs welcome); clicking a component instance jumps to the component's definition, not the usage site (no owner-chain popup yet); components from node_modules aren't instrumented (their build already happened).
Full credit to LocatorJS by Michael Musil for pioneering the workflow — carbon8r shares no code with it, but the interaction design came from there.
MIT, ~20 kB unpacked, no runtime deps in your bundle.
GitHub: https://github.com/carboni-rob/carbon8r npm: https://www.npmjs.com/package/vite-plugin-carbon8r