element-source

Get the source file location of any DOM element.

React
Vue
Svelte
Solid
localhost:3000
My App
BrandLogo ยท src/BrandLogo.tsx:5:3
Click any element to jump straight to its source. Works with any framework, bundler, or runtime.

Installation

npm install element-source

Quick Start

Pass any DOM element to resolveElementInfo to get its source file location, component name, and full component stack.

import { resolveElementInfo } from "element-source";

const info = await resolveElementInfo(element);
// {
//   tagName: "button",
//   componentName: "App",
//   source: { filePath: "src/App.tsx", lineNumber: 42, columnNumber: 10, componentName: "App" },
//   stack: [...]
// }

API

resolveElementInfo(node: object): Promise<ElementInfo>

Returns complete metadata: tag name, component name, source location, and full stack.

const info = await resolveElementInfo(document.querySelector("#root button"));
// {
//   tagName: "button",
//   componentName: "Counter",
//   source: { filePath: "src/Counter.tsx", lineNumber: 12, columnNumber: 5, componentName: "Counter" },
//   stack: [
//     { filePath: "src/Counter.tsx", lineNumber: 12, columnNumber: 5, componentName: "Counter" },
//     { filePath: "src/App.tsx", lineNumber: 8, columnNumber: 3, componentName: "App" },
//   ]
// }

resolveSource(node: object): Promise<ElementSourceInfo | null>

Returns the primary source location.

const source = await resolveSource(element);
// { filePath: "src/Counter.tsx", lineNumber: 12, columnNumber: 5, componentName: "Counter" }

resolveStack(node: object): Promise<ElementSourceInfo[]>

Returns the full stack of source frames (React + framework combined).

const stack = await resolveStack(element);
// [
//   { filePath: "src/Counter.tsx", lineNumber: 12, columnNumber: 5, componentName: "Counter" },
//   { filePath: "src/App.tsx", lineNumber: 8, columnNumber: 3, componentName: "App" },
// ]

resolveComponentName(node: object): Promise<string | null>

Returns the nearest user-defined component name.

const name = await resolveComponentName(element);
// "Counter"

createSourceResolver(options?: ResolverOptions)

Creates a resolver with custom framework resolvers.

import { createSourceResolver, svelteResolver, vueResolver } from "element-source";

const { resolveSource, resolveStack, resolveComponentName, resolveElementInfo } =
  createSourceResolver({
    resolvers: [svelteResolver, vueResolver],
  });

const info = await resolveElementInfo(element);

formatStackFrame(frame: ElementSourceInfo): string

Formats a single source frame as a stack-trace-style string.

const frame = { filePath: "src/App.tsx", lineNumber: 42, columnNumber: 10, componentName: "App" };
formatStackFrame(frame);
// "\n  in App (at src/App.tsx:42:10)"

formatStack(stack: ElementSourceInfo[], maxLines?: number): string

Formats an array of source frames.

const stack = [
  { filePath: "src/Counter.tsx", lineNumber: 12, columnNumber: 5, componentName: "Counter" },
  { filePath: "src/App.tsx", lineNumber: 8, columnNumber: 3, componentName: "App" },
];
formatStack(stack);
// "\n  in Counter (at src/Counter.tsx:12:5)\n  in App (at src/App.tsx:8:3)"

formatStack(stack, 1);
// "\n  in Counter (at src/Counter.tsx:12:5)"

getTagName(node: object): string

Returns the tag name from any host instance. Handles DOM Element.tagName, Ink nodeName, and falls back to "".

getTagName(document.createElement("div")); // "div"
getTagName({ nodeName: "ink-text" });       // "ink-text"
getTagName({});                             // ""