# Svelte Preprocessor
The Svelte preprocessor expands Macroforge macros in `<script>` blocks before Svelte compilation, enabling seamless macro usage in Svelte components.
## Installation
Bash
```
npm install -D @macroforge/svelte-preprocessor
```
## Configuration
Add the preprocessor to your `svelte.config.js`:
svelte.config.js
```
import adapter from '@sveltejs/adapter-auto';
import { vitePreprocess } from '@sveltejs/vite-plugin-svelte';
import { macroforgePreprocess } from '@macroforge/svelte-preprocessor';
/** @type {import('@sveltejs/kit').Config} */
const config = {
preprocess: [
macroforgePreprocess(), // Expand macros FIRST
vitePreprocess() // Then handle TypeScript/CSS
],
kit: {
adapter: adapter()
}
};
export default config;
```
Warning
Always place `macroforgePreprocess()` **before** other preprocessors like `vitePreprocess()`. This ensures macros are expanded before TypeScript compilation.
## Usage
Use `@derive` decorators directly in your Svelte component scripts:
UserCard.svelte
```
<script lang="ts">
/** @derive(Debug, Clone) */
class User {
name: string;
email: string;
constructor(name: string, email: string) {
this.name = name;
this.email = email;
}
}
let user = new User("Alice", "alice@example.com");
console.log(user.toString()); // Generated by Debug macro
</script>
<p>User: {user.name}</p>
```
## Options
TypeScript
```
macroforgePreprocess({
// Keep @derive decorators in output (for debugging)
keepDecorators: false,
// Process JavaScript files (not just TypeScript)
processJavaScript: false
})
```
### Option Reference
| Option | Type | Default | Description |
| ------------------- | --------- | ------- | --------------------------------------------- |
| `keepDecorators` | `boolean` | `false` | Keep decorators in output |
| `processJavaScript` | `boolean` | `false` | Process `<script>` blocks without `lang="ts"` |
## How It Works
The preprocessor:
1. Intercepts `<script lang="ts">` blocks in `.svelte` files
2. Checks for `@derive` decorators (skips files without them)
3. Expands macros using the native Macroforge binary
4. Returns the transformed code for Svelte compilation
Tip
Files without `@derive` decorators are passed through unchanged with zero overhead.
## SvelteKit Integration
For SvelteKit projects, you can use both the preprocessor (for `.svelte` files) and the Vite plugin (for standalone `.ts` files):
svelte.config.js
```
// svelte.config.js
import { macroforgePreprocess } from '@macroforge/svelte-preprocessor';
import { vitePreprocess } from '@sveltejs/vite-plugin-svelte';
export default {
preprocess: [
macroforgePreprocess(),
vitePreprocess()
]
};
```
vite.config.ts
```
// vite.config.ts
import macroforge from '@macroforge/vite-plugin';
import { sveltekit } from '@sveltejs/kit/vite';
import { defineConfig } from 'vite';
export default defineConfig({
plugins: [
macroforge(), // For .ts files
sveltekit()
]
});
```
## Using with Vitest
The preprocessor works seamlessly with Vitest for testing Svelte components:
vitest.config.ts
```
// vitest.config.ts
import { defineConfig } from 'vitest/config';
import { sveltekit } from '@sveltejs/kit/vite';
import { svelteTesting } from '@testing-library/svelte/vite';
import macroforge from '@macroforge/vite-plugin';
export default defineConfig({
plugins: [
macroforge(),
sveltekit(),
svelteTesting()
],
test: {
environment: 'jsdom',
include: ['src/**/*.{test,spec}.{js,ts}']
}
});
```
## Svelte 5 Runes Compatibility
The preprocessor is fully compatible with Svelte 5 runes (`$state`, `$derived`, `$props`, etc.). Files using runes but without `@derive` decorators are skipped entirely.
Svelte
```
<script lang="ts">
// Runes work normally
let count = $state(0);
let doubled = $derived(count * 2);
// Macros expand correctly
/** @derive(Debug) */
class Counter {
value: number;
constructor(value: number) {
this.value = value;
}
}
</script>
```