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

If you're using Preact, import preact/debug in development so owner stacks and source locations are available.

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({}); // ""