Vue DX
Zero-config DX for Vue 3 + Vite projects: named router-view autocomplete,
IntelliSense for global components and directives, auto-generated jsconfig.
No config files to commit, no per-project setup.
Why
In a Vue project, some "magic strings" get no editor support at all:
- the keys of
components: {} in route records must match the <router-view name="..."> in your layouts, but the link only exists at runtime — VSCode suggests everything except the right names;
- components registered with
app.component(...) and directives registered with app.directive(...) are invisible to Volar without a .d.ts augmenting GlobalComponents/GlobalDirectives;
- aliases defined in
vite.config don't apply to IntelliSense until they're replicated in jsconfig.json.
The classic solutions (codegen scripts, JSDoc annotations, config files) have to be maintained per project and clutter your repos. Vue DX moves all of this into the editor: install it once and it works on any Vue + Vite workspace, present or future.
What it does
🧭 Named router-views in route records
The <router-view name="..."> of all your layouts are indexed (any .vue file under src/, no required structure). Inside a route record's components: {} you get:
- Autocomplete for view names, prioritized above generic suggestions;
- Go to definition from the key to the matching
<router-view> in the layout;
- Diagnostics: warnings on keys that don't exist in any layout (the typos no type-check would ever catch).
An object is treated as a route record if it has path among the sibling keys of components, or if the file lives in a router/routes folder — Options API components: {} objects are left alone. The detection is textual and tolerant, so it works even while the code is syntactically incomplete (i.e. while you're typing).
⚙️ Automatic codegen
On workspace open and on every save of the relevant files, the extension regenerates:
| File |
Content |
Source |
jsconfig.json |
compilerOptions.paths |
aliases from vite.config.* |
components.d.ts |
GlobalComponents for Volar |
.component('Name', X) calls anywhere under src/ |
directives.d.ts |
GlobalDirectives (v-focus → vFocus) |
.directive('name', ...) calls anywhere under src/ |
The details that matter:
- Git sees nothing: generated files are hidden via
skip-worktree (if tracked) or .git/info/exclude (if untracked). Commits, diffs and pushes stay clean.
- Smart watchers: edit a file that registers components/directives and the
.d.ts files update on their own, with debounce. New files introducing registrations are picked up automatically too.
- Writes only when needed: if the generated content is identical, the file isn't touched — no pointless tsserver/Volar restarts.
- Reliable aliases: the
vite.config is loaded through Vite in a separate Node process; if loading fails (missing dependencies, exotic configs) a static fallback parser kicks in.
- Default and named imports are supported; relative imports are resolved against the registering file.
- Lines added by hand to
directives.d.ts (e.g. directives from third-party libraries) are preserved.
Getting started
Install the extension and open a Vue + Vite project — that's it. Vue DX activates on its own in workspaces that have a vite.config.* and vue among the dependencies.
It requires a trusted workspace (it runs the project's vite.config and writes the generated files).
Commands
| Command |
Description |
Vue DX: Regenerate configuration (jsconfig + d.ts) |
Manually regenerate across all projects in the workspace |
Vue DX: Show output |
Log of what was generated and which files are being watched |
Settings
| Key |
Default |
Description |
vueDx.autoGenerate |
true |
Codegen on workspace open and on save |
vueDx.routerViewSuggestions |
true |
Named router-view autocomplete |
vueDx.diagnostics |
true |
Warnings on non-existent named views |
Known limitations
- Named view suggestions are the union of all layouts in the project: knowing which layout serves a specific route would require statically resolving the route tree (a possible future evolution).
- Dynamically built registrations (loops, computed names) can't be detected statically.
- Dynamic
<router-view :name="..."> are ignored; those without a name count as default.
License
MIT — © 2026 Able S.r.l.