element-source: The Library That Turns a DOM Node Into a Source File
element-source maps live elements back to the code that rendered them across React, Vue, Svelte, Solid, and Preact.

I originally built this to power React Grab, a way to select elements in the browser and give the source as context to coding agents. Agents are incredibly good and token efficient at using file sources. Now anyone can use what makes React Grab possible.
- element-source turns a clicked DOM node into a unified source location, stack, and component name across multiple frontend frameworks.
- Its real trick is a resolver pipeline that normalizes very different dev-mode metadata into one API.
- The project is built for AI coding agents as much as for humans, because precise file context beats vague screenshots.
- The hardest resolver paths show the trade-off clearly: more runtime work buys better source attribution in otherwise opaque UIs.
Most tools can tell you what the browser rendered. element-source tries to tell you where it came from, down to the file, line, column, and component stack. That makes it useful for browser inspectors, design-to-code tools, and AI agents that need source context instead of guesswork.
Why this exists
The project came out of React Grab, Aiden Bai's browser picker for coding agents. That origin explains the shape of the library. It is not trying to be another devtools pane. It is trying to extract one thing reliably: the source behind a visible element.
What makes it different
The differentiator is not just that it supports several frameworks. It is that it turns framework-specific debugging crumbs into a single runtime primitive. You hand it an element, and it works through the framework's own hidden metadata to reconstruct provenance.
The code follows a chain of responsibility. React gets first pass through bippy and Fiber. If that does not resolve, the default resolvers move through Vue, Svelte, Solid, and Preact, each adapter translating its framework's private debug data into one shared ElementSourceInfo shape.
import {
resolveSource,
resolveStack,
resolveComponentName
} from 'element-source';
async function inspect(el: Element) {
const source = await resolveSource(el);
const stack = await resolveStack(el);
const name = await resolveComponentName(el);
return { source, stack, name };
}
A library could tell you the exact file path and line number. Across React, Vue, Svelte, and Solid. No build plugin. No browser extension. That’s what element-source does. It shipped on March 13, 2026
How the adapters work
Each framework exposes a different clue. Vue leans on dev-mode markers like data-v-inspector and __vueParentComponent. Svelte hides metadata on __svelte_meta and reconstructs the stack by walking parent links. React is the most involved because it uses Fiber internals and special handling for modern meta-framework frames. Solid is the most aggressive fallback, because it has to infer source from runtime clues and loaded resources instead of a tidy component tree.
That is the real engineering move here. The library does not pretend all frameworks expose the same surface area. It accepts that they do not, then spends its complexity budget on normalization.
How it compares
| Approach | What it can tell you | Trade-off |
|---|---|---|
| Native framework DevTools | Component structure and source hints in the browser | Usually a manual inspection tool, not a programmable runtime API. |
| Build-time source maps | Compiled code back to original files | They do not answer which live DOM node produced the element. |
| element-source | A live element's file, line, name, and stack | Depends on dev-mode metadata and framework internals. |
| Browser extensions and overlays | Helpful visual context for humans | They rarely give clean data back to application code or agents. |
That comparison is the point. element-source is not trying to replace devtools or source maps. It fills the gap between them: a lightweight runtime query that connects a visible element to the exact source context an editor, inspector, or agent can act on.
The trade-off is clear. This is a developer tool built on debug metadata, not a production tracing system. But if your job is to close the loop between what the user sees and what the codebase contains, that is exactly the right bargain.