vite plugin #
The Vite plugin is the recommended path for SvelteKit
and Vite projects. It runs analysis at build time and serves the result as 'virtual:svelte-docinfo'; in dev mode it watches source
files and sends HMR updates as you edit.
Setup #
Add the plugin to
vite.config.ts:import {defineConfig} from 'vite'; import {sveltekit} from '@sveltejs/kit/vite'; import svelteDocinfo from 'svelte-docinfo/vite.js'; export default defineConfig({ plugins: [sveltekit(), svelteDocinfo()], });Add TypeScript support in your
app.d.ts:/// <reference types="svelte-docinfo/virtual-svelte-docinfo.js" />Import the virtual module anywhere in your app:
import {modules, diagnostics} from 'virtual:svelte-docinfo'; // or use the default export: import data from 'virtual:svelte-docinfo'; // data.modules and data.diagnostics are the same as the named exportsBoth exports match the programmatic AnalyzeResultJson shape. See diagnostics for what flows through
diagnostics.
If TypeScript reports Cannot find module 'virtual:svelte-docinfo', ensure the /// <reference> line is in your app.d.ts.
Options #
All options are optional; the minimal call uses defaults (package.json exports discovery, glob fallback):
svelteDocinfo() Every option, with its default:
import svelteDocinfo from 'svelte-docinfo/vite.js';
svelteDocinfo({
// Project root directory. Default: Vite's resolved config.root.
projectRoot: process.cwd(),
// Glob patterns for file discovery. Forces glob mode under discovery: 'auto'.
// Default: undefined (use exports discovery).
include: ['src/**/*.ts', 'src/**/*.svelte'],
// Exclude globs. When provided, fully replaces the default
// ['**/*.test.ts', '**/*.spec.ts'] — re-include those patterns
// explicitly if you want them filtered.
exclude: ['**/*.test.ts', '**/*.spec.ts'],
// Discovery strategy: 'auto' | 'exports' | 'glob'. Default: 'auto'.
// 'auto' → exports first, glob fallback
// 'exports' → strict; throws if package.json exports is missing
// 'glob' → skip exports, use glob patterns
discovery: 'auto',
// Dist directory for exports discovery. Default: 'dist'.
distDir: 'dist',
// Resolve module dependency graph. Default: true.
resolveDependencies: true,
// Dispatch on duplicate declaration names across modules.
// 'throw' | 'warn' | (duplicates, log) => void.
// Default: undefined — the duplicate_declaration diagnostic still emits,
// but no extra dispatch fires. Set to 'throw' to fail fast on duplicates.
onDuplicates: undefined,
// Partial overrides for default source options (SvelteKit src/lib layout).
// Merged into createSourceOptions(projectRoot, sourceOptions).
sourceOptions: {sourcePaths: ['src/lib']},
// HMR debounce in ms. Default: 100.
hmrDebounceMs: 100,
}) The plugin runs the same pipeline as analyzeFromFiles internally: discover
via discoverSourceFiles, resolve dependencies, then analyze. sourceOptions is merged with defaults via createSourceOptions before discovery; hmrDebounceMs only affects the dev-mode watcher.
CLI vs Vite plugin #
The CLI calls analyzeFromFiles once, so use it for CI pipelines and one-off generation. The plugin owns a persistent createAnalysisSession, so HMR re-analyses reuse parsed TypeScript ASTs and svelte2tsx output across cycles. Use it when the analysis feeds the SvelteKit/Vite bundle. See the session guide if you're driving a session directly (custom bundler, LSP, etc.).
How it works #
The plugin hooks into four Vite lifecycle stages:
- configResolved: throws synchronously when
discovery: 'exports'is combined withinclude, so contradictory configs fail at startup rather than at first analysis - buildStart: discovers the source set, reads file contents, and runs createAnalysisSession's
analyze; caches the serialized JSON result - resolveId / load: serves the cached result as
virtual:svelte-docinfo, a JavaScript module exportingmodules,diagnostics, and a default{modules, diagnostics} - configureServer: watches source directories for changes, debounces re-analysis, and sends HMR updates only when the output actually changes. The session diffs incoming files by content equality, so unchanged files skip re-parsing entirely.