{"id":50317608,"url":"https://github.com/aidenybai/element-source","last_synced_at":"2026-05-29T01:03:06.346Z","repository":{"id":344381617,"uuid":"1178755725","full_name":"aidenybai/element-source","owner":"aidenybai","description":"Get the source file location of any DOM element. Works with React, Vue, Svelte, Solid, Preact","archived":false,"fork":false,"pushed_at":"2026-03-17T05:22:45.000Z","size":1530,"stargazers_count":403,"open_issues_count":0,"forks_count":11,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-04-03T13:31:25.884Z","etag":null,"topics":["element-source","react","solid","source","svelte","vue"],"latest_commit_sha":null,"homepage":"https://element-source.com","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/aidenybai.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":"AGENTS.md","dco":null,"cla":null}},"created_at":"2026-03-11T10:35:57.000Z","updated_at":"2026-04-03T08:32:04.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/aidenybai/element-source","commit_stats":null,"previous_names":["aidenybai/element-source"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/aidenybai/element-source","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aidenybai%2Felement-source","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aidenybai%2Felement-source/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aidenybai%2Felement-source/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aidenybai%2Felement-source/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/aidenybai","download_url":"https://codeload.github.com/aidenybai/element-source/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aidenybai%2Felement-source/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":33632272,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-05-28T02:00:06.440Z","response_time":99,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["element-source","react","solid","source","svelte","vue"],"created_at":"2026-05-29T01:03:04.982Z","updated_at":"2026-05-29T01:03:06.341Z","avatar_url":"https://github.com/aidenybai.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# element-source\n\nGet the source file location of any DOM element. Works with React, Preact, Vue, Svelte, and Solid.\n\n\u003e I originally built this to power [React Grab](https://www.react-grab.com/blog/intro), a way to select elements in the browser and give the source as context to coding agents. Agents are incredibly good and [token efficient](https://www.react-grab.com/blog/intro) at using file sources. Now anyone can use what makes React Grab possible.\n\n## Installation\n\n```bash\nnpm install element-source\n```\n\nIf you're using Preact, import `preact/debug` in development so owner stacks and source locations are available.\n\n## Quick Start\n\nPass any DOM element to `resolveElementInfo` to get its source file location, component name, and full component stack.\n\n```ts\nimport { resolveElementInfo } from \"element-source\";\n\nconst info = await resolveElementInfo(element);\n// {\n//   tagName: \"button\",\n//   componentName: \"App\",\n//   source: { filePath: \"src/App.tsx\", lineNumber: 42, columnNumber: 10, componentName: \"App\" },\n//   stack: [...]\n// }\n```\n\n## API\n\n### `resolveElementInfo(node: object): Promise\u003cElementInfo\u003e`\n\nReturns complete metadata: tag name, component name, source location, and full stack.\n\n```ts\nconst info = await resolveElementInfo(document.querySelector(\"#root button\"));\n// {\n//   tagName: \"button\",\n//   componentName: \"Counter\",\n//   source: { filePath: \"src/Counter.tsx\", lineNumber: 12, columnNumber: 5, componentName: \"Counter\" },\n//   stack: [\n//     { filePath: \"src/Counter.tsx\", lineNumber: 12, columnNumber: 5, componentName: \"Counter\" },\n//     { filePath: \"src/App.tsx\", lineNumber: 8, columnNumber: 3, componentName: \"App\" },\n//   ]\n// }\n```\n\n### `resolveSource(node: object): Promise\u003cElementSourceInfo | null\u003e`\n\nReturns the primary source location.\n\n```ts\nconst source = await resolveSource(element);\n// { filePath: \"src/Counter.tsx\", lineNumber: 12, columnNumber: 5, componentName: \"Counter\" }\n```\n\n### `resolveStack(node: object): Promise\u003cElementSourceInfo[]\u003e`\n\nReturns the full stack of source frames (React + framework combined).\n\n```ts\nconst stack = await resolveStack(element);\n// [\n//   { filePath: \"src/Counter.tsx\", lineNumber: 12, columnNumber: 5, componentName: \"Counter\" },\n//   { filePath: \"src/App.tsx\", lineNumber: 8, columnNumber: 3, componentName: \"App\" },\n// ]\n```\n\n### `resolveComponentName(node: object): Promise\u003cstring | null\u003e`\n\nReturns the nearest user-defined component name.\n\n```ts\nconst name = await resolveComponentName(element);\n// \"Counter\"\n```\n\n### `createSourceResolver(options?: ResolverOptions)`\n\nCreates a resolver with custom framework resolvers.\n\n```ts\nimport { createSourceResolver, svelteResolver, vueResolver } from \"element-source\";\n\nconst { resolveSource, resolveStack, resolveComponentName, resolveElementInfo } =\n  createSourceResolver({\n    resolvers: [svelteResolver, vueResolver],\n  });\n\nconst info = await resolveElementInfo(element);\n```\n\n### `formatStackFrame(frame: ElementSourceInfo): string`\n\nFormats a single source frame as a stack-trace-style string.\n\n```ts\nconst frame = { filePath: \"src/App.tsx\", lineNumber: 42, columnNumber: 10, componentName: \"App\" };\nformatStackFrame(frame);\n// \"\\n  in App (at src/App.tsx:42:10)\"\n```\n\n### `formatStack(stack: ElementSourceInfo[], maxLines?: number): string`\n\nFormats an array of source frames.\n\n```ts\nconst stack = [\n  { filePath: \"src/Counter.tsx\", lineNumber: 12, columnNumber: 5, componentName: \"Counter\" },\n  { filePath: \"src/App.tsx\", lineNumber: 8, columnNumber: 3, componentName: \"App\" },\n];\nformatStack(stack);\n// \"\\n  in Counter (at src/Counter.tsx:12:5)\\n  in App (at src/App.tsx:8:3)\"\n\nformatStack(stack, 1);\n// \"\\n  in Counter (at src/Counter.tsx:12:5)\"\n```\n\n### `getTagName(node: object): string`\n\nReturns the tag name from any host instance. Handles DOM `Element.tagName`, Ink `nodeName`, and falls back to `\"\"`.\n\n```ts\ngetTagName(document.createElement(\"div\")); // \"div\"\ngetTagName({ nodeName: \"ink-text\" }); // \"ink-text\"\ngetTagName({}); // \"\"\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Faidenybai%2Felement-source","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Faidenybai%2Felement-source","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Faidenybai%2Felement-source/lists"}