or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

examples

edge-cases.mdreal-world-scenarios.md
index.md
tile.json

compiler.mddocs/reference/

Svelte Compiler API

The Svelte compiler transforms .svelte component files and JavaScript/TypeScript modules into efficient JavaScript code. This module (svelte/compiler) provides programmatic access to compilation, parsing, preprocessing, and migration utilities.

Version: 5.46.1 Module: svelte/compiler

Functions

compile() { .api }

Compiles Svelte component source code into a JavaScript module.

Signature:

function compile(
  source: string,
  options?: CompileOptions
): CompileResult

Parameters:

  • source (string): The .svelte component source code to compile
  • options (CompileOptions, optional): Compiler configuration options

Returns: CompileResult - Object containing compiled JavaScript, CSS, warnings, and metadata

Usage Example:

import { compile } from 'svelte/compiler';

const result = compile(`
  <script>
    let count = $state(0);
  </script>

  <button onclick={() => count++}>
    Clicks: {count}
  </button>

  <style>
    button { color: blue; }
  </style>
`, {
  filename: 'Counter.svelte',
  dev: true,
  generate: 'client'
});

console.log(result.js.code);  // Compiled JavaScript
console.log(result.css.code); // Compiled CSS
console.log(result.warnings); // Any compiler warnings

compileModule() { .api }

Compiles JavaScript or TypeScript source code containing Svelte runes into a JavaScript module. This is used for .svelte.js and .svelte.ts files that use runes outside of components.

Signature:

function compileModule(
  source: string,
  options?: ModuleCompileOptions
): CompileResult

Parameters:

  • source (string): JavaScript/TypeScript source code with runes
  • options (ModuleCompileOptions, optional): Module compilation options

Returns: CompileResult - Object containing compiled JavaScript and metadata (no CSS)

Usage Example:

import { compileModule } from 'svelte/compiler';

const result = compileModule(`
  export const count = $state(0);
  export const doubled = $derived(count * 2);
`, {
  filename: 'store.svelte.js',
  dev: false,
  generate: 'client'
});

console.log(result.js.code);
console.log(result.metadata.runes); // Always true for compileModule

parse() { .api }

Parses Svelte component source code into an Abstract Syntax Tree (AST) without compiling it. The modern option controls which AST format is returned.

Signature (modern AST):

function parse(
  source: string,
  options: {
    filename?: string;
    modern: true;
    loose?: boolean;
  }
): AST.Root

Signature (legacy AST):

function parse(
  source: string,
  options?: {
    filename?: string;
    modern?: false;
    loose?: boolean;
  }
): Record<string, any>

Parameters:

  • source (string): The Svelte component source code to parse
  • options (object, optional):
    • filename (string): Filename for error messages and debugging
    • modern (boolean): If true, returns modern AST. If false or omitted, returns legacy AST. Default: false in Svelte 5, will become true in Svelte 6
    • loose (boolean): If true, enables loose parsing mode that tolerates some syntax errors

Returns: AST.Root (if modern: true) or legacy AST object

Usage Example:

import { parse } from 'svelte/compiler';

// Parse with modern AST (recommended)
const ast = parse(`
  <script>
    let name = 'world';
  </script>

  <h1>Hello {name}!</h1>
`, {
  filename: 'Component.svelte',
  modern: true
});

console.log(ast.type);        // 'Root'
console.log(ast.fragment);    // Fragment containing nodes
console.log(ast.instance);    // Parsed <script> element
console.log(ast.css);         // Parsed <style> element (if exists)

preprocess() { .api }

Preprocesses Svelte component source code through one or more transformation steps. Commonly used for TypeScript, SCSS, PostCSS, and other transformations before compilation.

Signature:

function preprocess(
  source: string,
  preprocessor: PreprocessorGroup | PreprocessorGroup[],
  options?: {
    filename?: string;
  }
): Promise<Processed>

Parameters:

  • source (string): The Svelte component source code to preprocess
  • preprocessor (PreprocessorGroup | PreprocessorGroup[]): Single preprocessor group or array of preprocessor groups to apply in sequence
  • options (object, optional):
    • filename (string): Filename for context and error messages

Returns: Promise<Processed> - Transformed source code with optional source map and dependencies

Usage Example:

import { preprocess } from 'svelte/compiler';
import typescript from 'svelte-preprocess';

const result = await preprocess(`
  <script lang="ts">
    let count: number = 0;
  </script>

  <button on:click={() => count++}>{count}</button>
`, [
  typescript()
], {
  filename: 'Component.svelte'
});

console.log(result.code);         // Transformed JavaScript
console.log(result.map);          // Source map
console.log(result.dependencies); // Additional files to watch

Preprocessor Group Structure:

const myPreprocessor: PreprocessorGroup = {
  name: 'my-preprocessor',

  // Transform entire markup
  markup: async ({ content, filename }) => {
    return {
      code: transformedContent,
      map: sourceMap,
      dependencies: ['file1.css']
    };
  },

  // Transform <script> blocks
  script: async ({ content, attributes, markup, filename }) => {
    if (attributes.lang === 'ts') {
      return {
        code: compiledJS,
        map: sourceMap
      };
    }
  },

  // Transform <style> blocks
  style: async ({ content, attributes, markup, filename }) => {
    if (attributes.lang === 'scss') {
      return {
        code: compiledCSS,
        map: sourceMap
      };
    }
  }
};

print() { .api }

Converts a modern Svelte AST node back into source code. This is useful for tools that parse, transform, and regenerate Svelte components.

Signature:

function print(
  ast: AST.SvelteNode,
  options?: {
    getLeadingComments?: Function;
    getTrailingComments?: Function;
  }
): {
  code: string;
  map: any;
}

Parameters:

  • ast (AST.SvelteNode): An AST node from parse() with modern: true, or any sub-node from a modern AST
  • options (object, optional):
    • getLeadingComments (Function): Function to retrieve leading comments from TypeScript nodes
    • getTrailingComments (Function): Function to retrieve trailing comments from TypeScript nodes

Returns: Object with:

  • code (string): Generated Svelte source code
  • map (SourceMap): Source map for the generated code

Usage Example:

import { parse, print } from 'svelte/compiler';

const ast = parse(source, { modern: true });

// Transform AST (example: modify text content)
ast.fragment.nodes.forEach(node => {
  if (node.type === 'Text') {
    node.data = node.data.toUpperCase();
  }
});

// Convert modified AST back to source
const result = print(ast);
console.log(result.code); // Regenerated Svelte source
console.log(result.map);  // Source map

Note: The output is valid Svelte code, but formatting details like whitespace and quote style may differ from the original source.

migrate() { .api }

Migrates Svelte 4 code to Svelte 5 syntax, converting to runes, event attributes (onclick vs on:click), and render tags. This is a best-effort migration that may throw errors for complex code.

Signature:

function migrate(
  source: string,
  options?: {
    filename?: string;
    use_ts?: boolean;
  }
): {
  code: string;
}

Parameters:

  • source (string): Svelte 4 component source code
  • options (object, optional):
    • filename (string): Filename for context and error messages
    • use_ts (boolean): Whether to generate TypeScript-compatible syntax

Returns: Object with:

  • code (string): Migrated Svelte 5 source code

Usage Example:

import { migrate } from 'svelte/compiler';

const svelte4Code = `
  <script>
    export let name = 'world';
    let count = 0;
  </script>

  <button on:click={() => count++}>
    Hello {name}! Count: {count}
  </button>
`;

const result = migrate(svelte4Code, {
  filename: 'Component.svelte',
  use_ts: true
});

console.log(result.code);
// Output uses $props(), $state(), and onclick instead of on:click

Note: May throw an error if the code is too complex to migrate automatically. Manual intervention may be required for complex components.

walk() { .api }

Deprecated: This function is deprecated. Use the estree-walker package directly instead.

import { walk } from 'estree-walker';

Constants

VERSION { .api }

The current version of Svelte as a string constant.

Type: string

Usage Example:

import { VERSION } from 'svelte/compiler';

console.log(`Using Svelte version: ${VERSION}`); // "5.46.1"

Types

CompileOptions { .api }

Configuration options for the compile() function. Extends ModuleCompileOptions with additional component-specific options.

Type Definition:

interface CompileOptions extends ModuleCompileOptions {
  // Component naming
  name?: string;

  // Custom element compilation
  customElement?: boolean;

  // Property accessors (Svelte 4 compatibility)
  accessors?: boolean;

  // Element namespace
  namespace?: 'html' | 'svg' | 'mathml';

  // Immutability hint (Svelte 4 compatibility)
  immutable?: boolean;

  // CSS handling
  css?: 'injected' | 'external';
  cssHash?: (args: {
    name: string;
    filename: string;
    css: string;
    hash: (input: string) => string;
  }) => string;

  // Code preservation
  preserveComments?: boolean;
  preserveWhitespace?: boolean;

  // DOM cloning strategy
  fragments?: 'html' | 'tree';

  // Runes mode
  runes?: boolean | undefined;

  // Version disclosure
  discloseVersion?: boolean;

  // Compatibility options
  compatibility?: {
    componentApi?: 4 | 5;
  };

  // Source maps
  sourcemap?: object | string;
  outputFilename?: string;
  cssOutputFilename?: string;

  // Hot module replacement
  hmr?: boolean;

  // AST format
  modernAst?: boolean;
}

Properties:

  • name (string, optional): Sets the name of the resulting JavaScript class. If unspecified, inferred from filename

  • customElement (boolean, optional): If true, generates a custom element constructor instead of a regular Svelte component. Default: false

  • accessors (boolean, optional): If true, creates getters/setters for component props. If false, only creates them for readonly exports. Automatically true when customElement: true. Default: false. Deprecated in runes mode

  • namespace ('html' | 'svg' | 'mathml', optional): Element namespace for the component. Default: 'html'

  • immutable (boolean, optional): If true, tells the compiler you won't mutate objects, allowing optimizations. Default: false. Deprecated in runes mode

  • css ('injected' | 'external', optional):

    • 'injected': Styles included in <head> during SSR and injected when component mounts
    • 'external': CSS only returned in compilation result for static extraction
    • Always 'injected' when customElement: true
  • cssHash (function, optional): Function that generates scoped CSS class names. Receives { hash, css, name, filename } and returns a string. Default: svelte-${hash(filename ?? css)}

  • preserveComments (boolean, optional): If true, preserves HTML comments in output. Default: false

  • preserveWhitespace (boolean, optional): If true, preserves whitespace as typed instead of collapsing. Default: false

  • fragments ('html' | 'tree', optional): DOM fragment cloning strategy:

    • 'html': Uses <template> with innerHTML (faster, but incompatible with strict CSP)
    • 'tree': Creates elements one-by-one then clones (slower, works everywhere)
    • Default: 'html'
    • Since: v5.33
  • runes (boolean | undefined, optional):

    • true: Forces runes mode
    • false: Disables runes even if detected
    • undefined: Infers from code (default)
    • Always true for compileModule()
    • Will default to true in Svelte 6
  • discloseVersion (boolean, optional): If true, exposes Svelte version in browser via window.__svelte.v. Default: true

  • compatibility (object, optional): Deprecated compatibility options:

    • componentApi (4 | 5): Set to 4 for Svelte 4-style component API. Default: 5
  • sourcemap (object | string, optional): Initial sourcemap to merge into final output (typically from preprocessor)

  • outputFilename (string, optional): Filename for JavaScript sourcemap

  • cssOutputFilename (string, optional): Filename for CSS sourcemap

  • hmr (boolean, optional): If true, compiles with hot module replacement support. Default: false

  • modernAst (boolean, optional): If true, returns modern AST format. Default: false. Will become true in Svelte 6

Inherited from ModuleCompileOptions:

  • dev (boolean, optional): Development mode with runtime checks. Default: false
  • generate ('client' | 'server' | false, optional): Target platform. Default: 'client'
  • filename (string, optional): Source filename for debugging and sourcemaps
  • rootDir (string, optional): Root directory for file path sanitization
  • warningFilter (function, optional): Filter function for warnings
  • experimental (object, optional): Experimental feature flags

ModuleCompileOptions { .api }

Configuration options for the compileModule() function and base options for compile().

Type Definition:

interface ModuleCompileOptions {
  dev?: boolean;
  generate?: 'client' | 'server' | false;
  filename?: string;
  rootDir?: string;
  warningFilter?: (warning: Warning) => boolean;
  experimental?: {
    async?: boolean;
  };
}

Properties:

  • dev (boolean, optional): If true, adds runtime checks and debugging information during development. Default: false

  • generate ('client' | 'server' | false, optional):

    • 'client': Emits code for browser execution
    • 'server': Emits code for server-side rendering
    • false: No code generation (useful for tooling that only needs warnings)
    • Default: 'client'
  • filename (string, optional): Source filename used for debugging hints and sourcemaps. Automatically set by bundler plugins

  • rootDir (string, optional): Root directory for ensuring filenames don't leak filesystem information. Automatically set by bundler plugins. Default: process.cwd() on Node.js, undefined elsewhere

  • warningFilter (function, optional): Filter function that receives a Warning and returns true to keep it or false to discard it

  • experimental (object, optional): Experimental feature flags (since v5.36):

    • async (boolean): Allows await keyword in deriveds, template expressions, and component top level

CompileResult { .api }

The result object returned by compile() and compileModule() functions.

Type Definition:

interface CompileResult {
  js: {
    code: string;
    map: SourceMap;
  };
  css: null | {
    code: string;
    map: SourceMap;
    hasGlobal: boolean;
  };
  warnings: Warning[];
  metadata: {
    runes: boolean;
  };
  ast: any;
}

Properties:

  • js (object): Compiled JavaScript output

    • code (string): Generated JavaScript code
    • map (SourceMap): Source map for the JavaScript
  • css (object | null): Compiled CSS output (null for compileModule() or when no styles exist)

    • code (string): Generated CSS code
    • map (SourceMap): Source map for the CSS
    • hasGlobal (boolean): Whether CSS includes :global() rules
  • warnings (Warning[]): Array of compiler warnings. Each warning has:

    • code (string): Warning category identifier
    • message (string): Human-readable description
    • start / end (object, optional): Location with line, column, and character properties
  • metadata (object): Compilation metadata

    • runes (boolean): Whether compiled in runes mode (always true for compileModule())
  • ast (any): The Abstract Syntax Tree of the compiled component

Usage Example:

const result = compile(source);

if (result.warnings.length > 0) {
  result.warnings.forEach(warning => {
    console.warn(`${warning.code}: ${warning.message}`);
    if (warning.start) {
      console.warn(`  at line ${warning.start.line}`);
    }
  });
}

// Write compiled output
writeFileSync('output.js', result.js.code);
if (result.css) {
  writeFileSync('output.css', result.css.code);
}

Warning { .api }

Represents a compiler warning with location information.

Type Definition:

interface Warning {
  code: string;
  message: string;
  filename?: string;
  start?: {
    line: number;
    column: number;
    character: number;
  };
  end?: {
    line: number;
    column: number;
    character: number;
  };
  position?: [number, number];
  frame?: string;
  stack?: string;
}

Properties:

  • code (string): Machine-readable warning category identifier (e.g., 'a11y-missing-attribute', 'unused-export-let')

  • message (string): Human-readable warning description

  • filename (string, optional): Source file that generated the warning

  • start (object, optional): Warning start location

    • line (number): Line number (1-indexed)
    • column (number): Column number (0-indexed)
    • character (number): Character offset in source
  • end (object, optional): Warning end location (same structure as start)

  • position (tuple, optional): Alternative position format as [start, end] character offsets

  • frame (string, optional): Code frame showing the warning location

  • stack (string, optional): Stack trace if applicable

CompileError { .api }

Represents a compilation error. Extends the standard Error class with location information.

Type Definition:

interface CompileError extends Error {
  code: string;
  message: string;
  filename?: string;
  start?: {
    line: number;
    column: number;
    character: number;
  };
  end?: {
    line: number;
    column: number;
    character: number;
  };
  position?: [number, number];
  frame?: string;
  stack?: string;
}

Properties: Same as Warning (see above), plus standard Error properties

Usage Example:

import { compile } from 'svelte/compiler';

try {
  const result = compile(invalidSource);
} catch (error) {
  if (error.code) {
    console.error(`Compilation error: ${error.code}`);
    console.error(error.message);
    if (error.start) {
      console.error(`at line ${error.start.line}, column ${error.start.column}`);
    }
    if (error.frame) {
      console.error(error.frame);
    }
  }
}

Processed { .api }

Result of preprocessing operations returned by preprocess() and preprocessor functions.

Type Definition:

interface Processed {
  code: string;
  map?: string | object;
  dependencies?: string[];
  attributes?: Record<string, string | boolean>;
  toString?: () => string;
}

Properties:

  • code (string): The transformed source code

  • map (string | object, optional): Source map mapping back to original code. Can be a JSON string or source map object

  • dependencies (string[], optional): Additional files to watch for changes (file paths that should trigger recompilation)

  • attributes (Record<string, string | boolean>, optional): For script/style preprocessors only - updated attributes to set on the tag. If undefined, attributes remain unchanged

  • toString (function, optional): Optional method that returns the code string

Usage Example:

// In a preprocessor
return {
  code: transformedCode,
  map: JSON.stringify(sourceMap),
  dependencies: ['./included-file.scss'],
  attributes: { lang: 'js', type: 'module' }
};

PreprocessorGroup { .api }

A collection of preprocessor functions for transforming different parts of a Svelte component.

Type Definition:

interface PreprocessorGroup {
  name?: string;
  markup?: MarkupPreprocessor;
  script?: Preprocessor;
  style?: Preprocessor;
}

Properties:

  • name (string, optional): Preprocessor name for identification. Will be required in next major version

  • markup (MarkupPreprocessor, optional): Function to transform entire component markup

  • script (Preprocessor, optional): Function to transform <script> blocks

  • style (Preprocessor, optional): Function to transform <style> blocks

Usage Example:

const preprocessor: PreprocessorGroup = {
  name: 'custom-preprocessor',

  markup: ({ content, filename }) => {
    // Transform entire component
    return {
      code: transformed,
      map: sourceMap
    };
  },

  script: ({ content, attributes, markup, filename }) => {
    // Only process TypeScript
    if (attributes.lang === 'ts') {
      return {
        code: compileTypeScript(content),
        attributes: { lang: 'js' }
      };
    }
  },

  style: ({ content, attributes, markup, filename }) => {
    // Process SCSS
    if (attributes.lang === 'scss') {
      return {
        code: compileSCSS(content)
      };
    }
  }
};

MarkupPreprocessor { .api }

Function type for preprocessing entire component markup.

Type Definition:

type MarkupPreprocessor = (options: {
  content: string;
  filename?: string;
}) => Processed | void | Promise<Processed | void>

Parameters:

  • options (object):
    • content (string): The complete Svelte file content
    • filename (string, optional): The filename of the Svelte file

Returns: Processed, void, Promise<Processed>, or Promise<void>

If no value or void is returned, the code is assumed unchanged.

Preprocessor { .api }

Function type for preprocessing <script> and <style> blocks.

Type Definition:

type Preprocessor = (options: {
  content: string;
  attributes: Record<string, string | boolean>;
  markup: string;
  filename?: string;
}) => Processed | void | Promise<Processed | void>

Parameters:

  • options (object):
    • content (string): The script or style tag content (not including the tags themselves)
    • attributes (Record<string, string | boolean>): Attributes from the script/style tag (e.g., { lang: 'ts', context: 'module' })
    • markup (string): The complete Svelte file content
    • filename (string, optional): The filename of the Svelte file

Returns: Processed, void, Promise<Processed>, or Promise<void>

If no value or void is returned, the code is assumed unchanged.

Usage Example:

const scriptPreprocessor: Preprocessor = async ({ content, attributes, filename }) => {
  if (attributes.lang === 'ts') {
    const compiled = await compileTypeScript(content, filename);
    return {
      code: compiled.code,
      map: compiled.map,
      attributes: { lang: 'js' } // Update to indicate JS output
    };
  }
};

AST Types

The compiler provides extensive type definitions for Abstract Syntax Trees. When using parse() with modern: true, you get a strongly-typed AST structure.

AST.Root { .api }

The root node of a parsed Svelte component AST.

Type Definition:

interface Root extends BaseNode {
  type: 'Root';
  options: SvelteOptions | null;
  fragment: Fragment;
  css: AST.CSS.StyleSheet | null;
  instance: Script | null;
  module: Script | null;
  comments: JSComment[];
}

Properties:

  • type (string): Always 'Root'
  • options (SvelteOptions | null): Parsed <svelte:options> element with inline compiler options
  • fragment (Fragment): The component's template fragment
  • css (AST.CSS.StyleSheet | null): Parsed <style> element, if exists
  • instance (Script | null): Parsed <script> element, if exists
  • module (Script | null): Parsed <script context="module"> element, if exists
  • comments (JSComment[]): Comments found in <script> and {expressions}

Inherited from BaseNode:

  • start (number): Starting character offset
  • end (number): Ending character offset

AST.Fragment { .api }

Represents a fragment of template nodes.

Type Definition:

interface Fragment {
  type: 'Fragment';
  nodes: Array<Text | Tag | ElementLike | Block | Comment>;
}

Properties:

  • type (string): Always 'Fragment'
  • nodes (array): Array of child nodes, which can be text, elements, blocks, or comments

AST Node Categories

The Svelte AST includes many node types organized into categories:

Element Nodes

  • RegularElement - Standard HTML elements (<div>, <span>, etc.)
  • SvelteElement - Dynamic elements (<svelte:element>)
  • SlotElement - Slot elements (<slot>)
  • TitleElement - Document title (<svelte:title>)
  • Component - Component instances
  • SvelteComponent - Dynamic components (<svelte:component>)
  • SvelteFragment - Fragment wrapper (<svelte:fragment>)
  • SvelteSelf - Recursive component reference (<svelte:self>)
  • SvelteWindow - Window bindings (<svelte:window>)
  • SvelteDocument - Document bindings (<svelte:document>)
  • SvelteBody - Body bindings (<svelte:body>)
  • SvelteHead - Head content (<svelte:head>)
  • SvelteOptions - Compiler options (<svelte:options>)

Block Nodes

  • IfBlock - Conditional rendering ({#if}...{/if})
  • EachBlock - List rendering ({#each}...{/each})
  • AwaitBlock - Async rendering ({#await}...{/await})
  • KeyBlock - Keyed rendering ({#key}...{/key})
  • SnippetBlock - Reusable snippets ({#snippet}...{/snippet})

Tag Nodes

  • ExpressionTag - Template expressions ({expression})
  • HtmlTag - Raw HTML ({@html expression})
  • RenderTag - Snippet rendering ({@render snippet()})
  • ConstTag - Local constants ({@const x = y})
  • DebugTag - Debug statements ({@debug vars})
  • AttachTag - Attachment API ({@attach expression})

Attribute and Directive Nodes

  • Attribute - Regular attributes
  • SpreadAttribute - Spread attributes ({...props})
  • Binding - Bind directives (bind:value)
  • ClassDirective - Class directives (class:name)
  • StyleDirective - Style directives (style:property)
  • OnDirective - Event handlers (on:click)
  • UseDirective - Actions (use:action)
  • TransitionDirective - Transitions (transition:fade)
  • AnimateDirective - Animations (animate:flip)
  • LetDirective - Slot props (let:name)

Text and Comments

  • Text - Static text content
  • Comment - HTML comments

AST.CSS Namespace { .api }

The CSS AST types represent parsed <style> blocks:

Types:

namespace AST.CSS {
  interface StyleSheet {
    type: 'StyleSheet';
    children: Array<Rule | Atrule>;
  }

  interface Rule {
    type: 'Rule';
    prelude: Selector[];
    block: Declaration[];
  }

  interface Selector {
    type: 'Selector';
    children: Array<SelectorNode>;
  }

  interface Declaration {
    type: 'Declaration';
    property: string;
    value: string;
    important?: boolean;
  }

  interface Atrule {
    type: 'Atrule';
    name: string;
    prelude?: any;
    block?: any;
  }
}

Usage Example:

import { parse } from 'svelte/compiler';

const ast = parse(source, { modern: true });

if (ast.css) {
  ast.css.children.forEach(rule => {
    if (rule.type === 'Rule') {
      console.log('Selectors:', rule.prelude);
      console.log('Declarations:', rule.block);
    }
  });
}

Complete Usage Example

Here's a comprehensive example showing how to use multiple compiler APIs together:

import {
  compile,
  preprocess,
  parse,
  print,
  VERSION
} from 'svelte/compiler';
import { readFileSync, writeFileSync } from 'fs';

console.log(`Using Svelte ${VERSION}`);

// 1. Read source file
const source = readFileSync('Component.svelte', 'utf-8');

// 2. Preprocess (TypeScript, SCSS, etc.)
const preprocessed = await preprocess(source, [
  {
    name: 'typescript',
    script: async ({ content, attributes }) => {
      if (attributes.lang === 'ts') {
        return {
          code: compileTypeScript(content),
          attributes: { lang: 'js' }
        };
      }
    }
  }
], {
  filename: 'Component.svelte'
});

// 3. Parse to AST for analysis
const ast = parse(preprocessed.code, {
  modern: true,
  filename: 'Component.svelte'
});

console.log('Component structure:', {
  hasScript: !!ast.instance,
  hasModuleScript: !!ast.module,
  hasStyles: !!ast.css,
  elementCount: ast.fragment.nodes.length
});

// 4. Optionally transform AST
// ... modify ast nodes ...

// 5. Convert back to source
const modified = print(ast);

// 6. Compile to JavaScript
const result = compile(modified.code, {
  filename: 'Component.svelte',
  dev: true,
  generate: 'client',
  css: 'external',
  runes: true
});

// 7. Handle warnings
if (result.warnings.length > 0) {
  console.warn('Compilation warnings:');
  result.warnings.forEach(w => {
    console.warn(`  [${w.code}] ${w.message}`);
  });
}

// 8. Write output
writeFileSync('output.js', result.js.code);
writeFileSync('output.js.map', JSON.stringify(result.js.map));

if (result.css) {
  writeFileSync('output.css', result.css.code);
  writeFileSync('output.css.map', JSON.stringify(result.css.map));
}

console.log('Compilation complete!');
console.log('Runes mode:', result.metadata.runes);

Migration from Svelte 4

When migrating from Svelte 4 to Svelte 5, use the migrate() function as a starting point:

import { migrate, compile } from 'svelte/compiler';
import { readFileSync, writeFileSync } from 'fs';

const svelte4Code = readFileSync('OldComponent.svelte', 'utf-8');

// Migrate to Svelte 5 syntax
try {
  const { code } = migrate(svelte4Code, {
    filename: 'OldComponent.svelte',
    use_ts: true
  });

  // Save migrated code
  writeFileSync('NewComponent.svelte', code);

  // Verify it compiles
  const result = compile(code, {
    filename: 'NewComponent.svelte',
    runes: true
  });

  if (result.warnings.length === 0) {
    console.log('Migration successful!');
  } else {
    console.log('Migration complete with warnings - review needed');
  }
} catch (error) {
  console.error('Migration failed:', error.message);
  console.error('Manual migration required for this component');
}

Best Practices

Development vs Production

Use different options for development and production builds:

const isDev = process.env.NODE_ENV !== 'production';

const result = compile(source, {
  dev: isDev,
  generate: 'client',
  css: 'external',
  discloseVersion: isDev,
  hmr: isDev
});

Warning Filtering

Filter out specific warnings you want to ignore:

const result = compile(source, {
  warningFilter: (warning) => {
    // Ignore a11y warnings in development
    if (isDev && warning.code.startsWith('a11y-')) {
      return false;
    }
    return true;
  }
});

Source Maps

Always provide filenames for better source maps:

const result = compile(source, {
  filename: 'Component.svelte',
  outputFilename: 'Component.js',
  cssOutputFilename: 'Component.css',
  sourcemap: preprocessorSourceMap
});

Custom Elements

Configure custom element compilation:

const result = compile(source, {
  customElement: true,
  css: 'injected', // Required for custom elements
  tag: 'my-component' // Can also use <svelte:options customElement="my-component">
});

Notes

  • The compiler is synchronous except for preprocess(), which is async
  • AST format is changing: modern: false (current default) will become modern: true in Svelte 6
  • Runes mode (runes: true) will become the default in Svelte 6
  • The walk() function is deprecated - use estree-walker package instead
  • Source maps require valid filenames to generate correct paths
  • The compiler throws CompileError for syntax errors and invalid code
  • Preprocessors run before compilation and can transform any part of the component
  • The print() function requires a modern AST (from parse() with modern: true)
  • Custom element compilation always uses injected CSS