Skip to content

Feature: Allow swapping the Svelte compiler module (pluggable compiler) #1348

Description

@baseballyama

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

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or requesttriageAwaiting triage by a project member

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions