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
#

  1. 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()], });
  2. Add TypeScript support in your app.d.ts:

    /// <reference types="svelte-docinfo/virtual-svelte-docinfo.js" />
  3. 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 exports

    Both 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:

  1. configResolved: throws synchronously when discovery: 'exports' is combined with include, so contradictory configs fail at startup rather than at first analysis
  2. buildStart: discovers the source set, reads file contents, and runs createAnalysisSession's analyze; caches the serialized JSON result
  3. resolveId / load: serves the cached result as virtual:svelte-docinfo, a JavaScript module exporting modules, diagnostics, and a default {modules, diagnostics}
  4. 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.