Describe the problem
Summary
Allow @sveltejs/vite-plugin-svelte to load a compiler module from a user-provided source instead of always importing svelte/compiler. This would allow alternative compiler implementations (Rust ports, profiling wrappers, debug tools, test mocks) without requiring a fork of this plugin.
Motivation
Today, users of an alternative Svelte compiler must fork vite-plugin-svelte only to change the compiler import. The change is usually the same in every fork: replace from 'svelte/compiler' with another module specifier. This creates unnecessary maintenance work because every upstream release must be rebased for a very small change.
Use cases
- Rust compiler ports — for example, rsvelte provides compile, compileModule, preprocess, and parse through an N-API module. Users currently need a forked plugin.
- Profiling / instrumentation wrappers — wrap the official compiler to collect timing data or inspect the AST.
- Test mocks — replace the compiler in unit tests without monkey-patching.
Describe the proposed solution
Add a compiler option to svelte():
import { svelte } from '@sveltejs/vite-plugin-svelte';
import * as rsvelte from '@rsvelte/compiler';
export default {
plugins: [
svelte({
// Option 1: pre-imported module
compiler: rsvelte,
// Option 2: module specifier
// compiler: '@rsvelte/compiler',
})
]
};
The compiler module must export the same API as svelte/compiler:
- compile(source, options): CompileResult
- compileModule(source, options): CompileResult
- parse(source, options): AST
- preprocess(source, preprocessors, options): Promise
- VERSION: string
Default behavior stays the same:
await import('svelte/compiler')
Implementation sketch
Resolve the user-provided compiler once during configResolved and store it on the existing PluginAPI object.
Replace static imports like:
import * as svelte from 'svelte/compiler'
with reads from api.compiler.
Resolution rules:
- compiler is a module object → use directly
- compiler is a string → await import(compiler)
- compiler is missing → await import('svelte/compiler')
The change should be small.
Considerations
- Type safety
Add a Compiler type (or re-export typeof import('svelte/compiler')) in public.d.ts. This would make incompatible compiler implementations fail with a TypeScript error instead of a runtime error.
- Version mismatch
Generated output must match the installed svelte runtime version. If compiler.VERSION differs from the installed svelte version, runtime issues are possible. Recommendation: show a warning during configResolved when versions do not match.
- Sourcemaps
No sourcemap changes are needed because the compile output format stays the same.
- Inspector / dep optimizer
vite-plugin-svelte-inspector and the dep optimizer use compile output and AST data, but do not directly import svelte/compiler, so they should not require changes.
Prior art
- postcss supports custom parsers and plugins
- rollup supports acornInjectPlugins
- vite supports customLogger
- esbuild-loader allows a custom esbuild instance
Out of scope
- Custom HMR or resolver hooks
Alternative compilers may provide extra features, but those should be discussed separately. This proposal only covers replacing the compiler import.
- Bundling the compiler
The compiler should still be resolved from the user’s project dependencies.
Alternatives considered
Keep fork of vite-plugin-svelte.
Importance
would make my life easier
Describe the problem
Summary
Allow
@sveltejs/vite-plugin-svelteto load a compiler module from a user-provided source instead of always importingsvelte/compiler. This would allow alternative compiler implementations (Rust ports, profiling wrappers, debug tools, test mocks) without requiring a fork of this plugin.Motivation
Today, users of an alternative Svelte compiler must fork
vite-plugin-svelteonly to change the compiler import. The change is usually the same in every fork: replacefrom 'svelte/compiler'with another module specifier. This creates unnecessary maintenance work because every upstream release must be rebased for a very small change.Use cases
Describe the proposed solution
Add a compiler option to
svelte():The compiler module must export the same API as
svelte/compiler:Default behavior stays the same:
Implementation sketch
Resolve the user-provided compiler once during configResolved and store it on the existing PluginAPI object.
Replace static imports like:
with reads from
api.compiler.Resolution rules:
The change should be small.
Considerations
Add a Compiler type (or re-export
typeof import('svelte/compiler')) inpublic.d.ts. This would make incompatible compiler implementations fail with a TypeScript error instead of a runtime error.Generated output must match the installed svelte runtime version. If
compiler.VERSIONdiffers from the installed svelte version, runtime issues are possible. Recommendation: show a warning during configResolved when versions do not match.No sourcemap changes are needed because the compile output format stays the same.
vite-plugin-svelte-inspectorand the dep optimizer use compile output and AST data, but do not directly importsvelte/compiler, so they should not require changes.Prior art
Out of scope
Alternative compilers may provide extra features, but those should be discussed separately. This proposal only covers replacing the compiler import.
The compiler should still be resolved from the user’s project dependencies.
Alternatives considered
Keep fork of
vite-plugin-svelte.Importance
would make my life easier