Vue Component References
A VS Code extension that answers "where is this .vue component used?" for Nuxt
projects with auto-imported components — the case the built-in tooling and
Volar's file-references can't reliably do.
- A CodeLens on the
<template> tag: N references.
- Clicking it opens the floating peek window with every usage.
- cmd/ctrl+click on the
<template> tag jumps to usages (single usage
navigates; multiple opens a peek list).
How it works
Every source file is AST-scanned (@vue/compiler-sfc for templates,
@babel/parser for scripts) into one targetVueFile -> usage locations index:
- Template tags (primary). Component tags resolve first against the file's
own default imports (
import Foo from './Foo.vue' → <Foo/> / <foo/>),
then against Nuxt's generated components.d.ts — the authoritative
component-name -> file map (so <BaseButton/>, kebab <base-button/>, and
shadcn <Button/> all resolve exactly as Nuxt resolves them).
<component :is="Foo"> / :is="'foo-card'" resolve too when is is a
static string, a string literal, or a locally imported / registry name.
- Imports.
import specifiers (incl. dynamic imports and re-exports)
resolve via relative paths + tsconfig/jsconfig/.nuxt/tsconfig.json /
Nuxt 4.1+ .nuxt/tsconfig.app.json aliases, covering composables and
components imported from .ts/.js files.
A FileSystemWatcher reindexes changed files incrementally; a second watcher
reloads the registry whenever Nuxt regenerates components.d.ts.
Requirements
Because the primary path relies on components.d.ts, run the dev server (or
nuxt prepare) at least once so .nuxt/[types/]components.d.ts exists. It
supports both the classic .nuxt/components.d.ts and the Nuxt 4.1+
.nuxt/types/components.d.ts location (including the off-by-one relative-path
quirk) by resolving each entry against disk.
Count semantics
References are <Tag> occurrences across templates — for auto-imported and
explicitly imported components alike, so navigation always lands on a real
usage. An import site itself only counts when the importing file doesn't use
the component in its template (e.g. route configs, defineAsyncComponent
wrappers, re-exports).
Run it
npm install
npm run compile # or: npm run watch
npm test # headless suite against the fixture repos in test/
Press F5 to launch an Extension Development Host, open your Nuxt repo there,
open any component under components/.
Package / install locally
npm run deploy # typecheck + esbuild bundle + vsce package
code --install-extension vue-component-references-0.1.0.vsix
Settings
| Setting |
Default |
Purpose |
vueRefs.include |
**/*.{vue,ts,js,mjs,cjs,tsx,jsx} |
Files scanned |
vueRefs.exclude |
**/{node_modules,dist,.nuxt,.output,.git,coverage}/** |
Ignored files |
vueRefs.scanTemplates |
true |
Resolve <Tag> usages via components.d.ts (auto-imports) |
vueRefs.maxFileSizeKB |
512 |
Skip files larger than this while indexing (0 = no limit) |
Command palette: "Vue Refs: Rebuild reference index" to force a full rebuild.
The index is cached per workspace (mtime-invalidated), so after the first cold
build (~seconds on a large monorepo, non-blocking) subsequent startups restore
in milliseconds and only changed files re-scan. Each rebuild logs a timing
summary to the Vue Component References output channel.
Limits / next steps
<component :is="someExpression"> with a computed/dynamic expression can't be
resolved statically (literals and identifier bindings are handled).
- Namespaced/icon component names (
IconMdi:check) from unplugin-icons are
parsed but won't match ordinary tag scans; harmless.