Spec RegistrySpec Registry

Help your agents use open-source better. Learn more.

Find usage specs for your project’s dependencies

>

npm-svelte

Describes: npmnpm/svelte

Description
A cybernetically enhanced web application framework that compiles to highly optimized JavaScript with reactive state management and component-based architecture.
Author
tessl
Last updated

How to use

npx @tessl/cli registry install tessl/npm-svelte@5.38.0

legacy.md docs/

1
# Legacy Compatibility
2
3
Svelte 5 provides compatibility utilities for migrating from Svelte 4 patterns and working with legacy components. These utilities help bridge the gap between the old reactivity system and the new runes-based approach.
4
5
## Capabilities
6
7
### createClassComponent
8
9
Creates a Svelte 4-style class component from a modern Svelte 5 component for backwards compatibility.
10
11
```typescript { .api }
12
/**
13
* Create a legacy class component from a modern Svelte 5 component
14
* @param component - Modern Svelte 5 component
15
* @returns Legacy class component with Svelte 4 API
16
*/
17
function createClassComponent<Props extends Record<string, any>, Exports extends Record<string, any>>(
18
component: Component<Props, Exports>
19
): LegacyComponentConstructor<Props, Exports>;
20
```
21
22
**Usage Examples:**
23
24
```typescript
25
import { createClassComponent } from "svelte/legacy";
26
import ModernComponent from "./ModernComponent.svelte";
27
28
// Create legacy wrapper
29
const LegacyComponent = createClassComponent(ModernComponent);
30
31
// Use with Svelte 4 patterns
32
const instance = new LegacyComponent({
33
target: document.getElementById("app"),
34
props: {
35
name: "World",
36
count: 0
37
}
38
});
39
40
// Legacy API methods
41
instance.$set({ count: 5 });
42
instance.$on("event", (event) => {
43
console.log("Event received:", event.detail);
44
});
45
46
// Legacy lifecycle
47
instance.$destroy();
48
49
// Access props and component references
50
console.log(instance.$$.props);
51
console.log(instance.$$.component);
52
```
53
54
### asClassComponent
55
56
Marks a Svelte 5 component to be compiled with legacy class component API for backwards compatibility.
57
58
```typescript { .api }
59
/**
60
* Mark a component to be compiled with legacy class component API
61
* @param component - Component constructor to mark as legacy
62
* @returns The same component with legacy compilation marker
63
*/
64
function asClassComponent<Props extends Record<string, any>, Exports extends Record<string, any>>(
65
component: Component<Props, Exports>
66
): Component<Props, Exports>;
67
```
68
69
**Usage Examples:**
70
71
```typescript
72
// ModernComponent.svelte - in <script> tag
73
import { asClassComponent } from "svelte/legacy";
74
75
// Mark this component for legacy compilation
76
export default asClassComponent(
77
// Component definition here
78
);
79
80
// Or in parent component
81
import { asClassComponent } from "svelte/legacy";
82
import Component from "./Component.svelte";
83
84
const LegacyWrappedComponent = asClassComponent(Component);
85
86
// Now can be used with legacy patterns
87
const instance = new LegacyWrappedComponent({
88
target: document.body,
89
props: { message: "Hello" }
90
});
91
```
92
93
### Legacy Component Patterns
94
95
Working with components that expect the old Svelte 4 component API.
96
97
**Migration Example:**
98
99
```typescript
100
// Before (Svelte 4)
101
import Component from "./Component.svelte";
102
103
const app = new Component({
104
target: document.getElementById("app"),
105
props: {
106
name: "world"
107
}
108
});
109
110
app.$set({ name: "svelte" });
111
app.$on("close", () => {
112
app.$destroy();
113
});
114
115
// After (Svelte 5 with legacy compatibility)
116
import { createClassComponent } from "svelte/legacy";
117
import Component from "./Component.svelte"; // Modern Svelte 5 component
118
119
const LegacyComponent = createClassComponent(Component);
120
121
const app = new LegacyComponent({
122
target: document.getElementById("app"),
123
props: {
124
name: "world"
125
}
126
});
127
128
app.$set({ name: "svelte" });
129
app.$on("close", () => {
130
app.$destroy();
131
});
132
```
133
134
### Interoperability Patterns
135
136
**Using Legacy Components in Modern Context:**
137
138
```typescript
139
// Modern parent component using legacy child
140
import { createClassComponent } from "svelte/legacy";
141
import LegacyChild from "./LegacyChild.svelte";
142
143
const LegacyChildClass = createClassComponent(LegacyChild);
144
145
let childInstance = $state(null);
146
let containerElement;
147
148
$effect(() => {
149
if (containerElement) {
150
childInstance = new LegacyChildClass({
151
target: containerElement,
152
props: {
153
data: someReactiveData
154
}
155
});
156
157
return () => {
158
childInstance?.$destroy();
159
};
160
}
161
});
162
163
// Update props reactively
164
$effect(() => {
165
if (childInstance) {
166
childInstance.$set({ data: someReactiveData });
167
}
168
});
169
```
170
171
**Legacy Event Handling:**
172
173
```typescript
174
import { createClassComponent } from "svelte/legacy";
175
import EventEmittingComponent from "./EventEmittingComponent.svelte";
176
177
const LegacyEventComponent = createClassComponent(EventEmittingComponent);
178
179
const instance = new LegacyEventComponent({
180
target: document.body
181
});
182
183
// Handle legacy events
184
instance.$on("customEvent", (event) => {
185
console.log("Custom event:", event.detail);
186
});
187
188
instance.$on("click", (event) => {
189
console.log("Click event:", event);
190
});
191
192
// Programmatic event dispatch (if supported by component)
193
instance.$set({ triggerEvent: true });
194
```
195
196
### Third-Party Library Integration
197
198
**Integrating with libraries that expect Svelte 4 components:**
199
200
```typescript
201
import { createClassComponent } from "svelte/legacy";
202
import MyComponent from "./MyComponent.svelte";
203
import ThirdPartyLibrary from "some-svelte4-library";
204
205
// Wrap modern component for legacy library
206
const WrappedComponent = createClassComponent(MyComponent);
207
208
// Use with third-party library that expects Svelte 4 API
209
const libraryInstance = new ThirdPartyLibrary({
210
component: WrappedComponent,
211
target: document.getElementById("container"),
212
props: {
213
title: "Hello World"
214
}
215
});
216
217
// Library can now use legacy API methods
218
libraryInstance.component.$set({ title: "Updated Title" });
219
libraryInstance.component.$on("change", handleChange);
220
```
221
222
### Component Factory Pattern
223
224
**Creating reusable legacy component factories:**
225
226
```typescript
227
import { createClassComponent } from "svelte/legacy";
228
229
// Factory function for creating legacy versions
230
function createLegacyFactory(modernComponent) {
231
const LegacyClass = createClassComponent(modernComponent);
232
233
return function createInstance(target, props = {}) {
234
return new LegacyClass({
235
target,
236
props,
237
// Default legacy options
238
intro: true,
239
anchor: null
240
});
241
};
242
}
243
244
// Usage
245
import Modal from "./Modal.svelte";
246
import Tooltip from "./Tooltip.svelte";
247
248
const createLegacyModal = createLegacyFactory(Modal);
249
const createLegacyTooltip = createLegacyFactory(Tooltip);
250
251
// Create instances with legacy API
252
const modal = createLegacyModal(document.body, {
253
title: "Confirmation",
254
message: "Are you sure?"
255
});
256
257
const tooltip = createLegacyTooltip(document.getElementById("help"), {
258
text: "Click for help",
259
position: "top"
260
});
261
```
262
263
## Types
264
265
```typescript { .api }
266
interface LegacyComponentConstructor<Props extends Record<string, any>, Exports extends Record<string, any>> {
267
new (options: {
268
target: Element | Document | ShadowRoot;
269
anchor?: Element;
270
props?: Props;
271
context?: Map<any, any>;
272
hydrate?: boolean;
273
intro?: boolean;
274
$$inline?: boolean;
275
}): LegacyComponentInstance<Props, Exports>;
276
}
277
278
interface LegacyComponentInstance<Props extends Record<string, any>, Exports extends Record<string, any>> {
279
/** Update component props */
280
$set(props: Partial<Props>): void;
281
282
/** Subscribe to component events */
283
$on(event: string, callback: (event: CustomEvent) => void): () => void;
284
285
/** Destroy component instance */
286
$destroy(): void;
287
288
/** Access to internal component state */
289
$$: {
290
props: Props;
291
component: Exports;
292
ctx: any;
293
};
294
}
295
296
interface Component<
297
Props extends Record<string, any> = {},
298
Exports extends Record<string, any> = {},
299
Bindings extends keyof Props | '' = string
300
> {
301
(internals: ComponentInternals, props: Props): Exports;
302
}
303
```
304
305
## Migration Strategies
306
307
### Gradual Migration
308
309
```typescript
310
// Phase 1: Wrap legacy components
311
import { createClassComponent } from "svelte/legacy";
312
import OldComponent from "./OldComponent.svelte";
313
314
const WrappedOldComponent = createClassComponent(OldComponent);
315
316
// Phase 2: Update usage patterns gradually
317
// Instead of: new OldComponent({...})
318
// Use: new WrappedOldComponent({...})
319
320
// Phase 3: Migrate component internals to runes
321
// Update OldComponent.svelte to use $state, $derived, etc.
322
323
// Phase 4: Remove legacy wrapper when ready
324
// import OldComponent from "./OldComponent.svelte";
325
// const instance = mount(OldComponent, {...});
326
```
327
328
### Testing Legacy Components
329
330
```typescript
331
import { createClassComponent } from "svelte/legacy";
332
import { render } from "@testing-library/svelte";
333
import Component from "./Component.svelte";
334
335
// Test modern component
336
test("modern component", () => {
337
const { getByText } = render(Component, { props: { name: "test" } });
338
expect(getByText("Hello test")).toBeInTheDocument();
339
});
340
341
// Test legacy wrapped component
342
test("legacy wrapped component", () => {
343
const LegacyComponent = createClassComponent(Component);
344
const container = document.createElement("div");
345
346
const instance = new LegacyComponent({
347
target: container,
348
props: { name: "test" }
349
});
350
351
expect(container.textContent).toContain("Hello test");
352
353
instance.$set({ name: "updated" });
354
expect(container.textContent).toContain("Hello updated");
355
356
instance.$destroy();
357
});
358
```
359
360
## Best Practices
361
362
1. **Use sparingly**: Legacy compatibility should be temporary during migration
363
2. **Test thoroughly**: Ensure legacy wrappers maintain expected behavior
364
3. **Document usage**: Clearly mark where legacy compatibility is being used
365
4. **Plan migration**: Create timeline for removing legacy compatibility
366
5. **Monitor performance**: Legacy wrappers may have performance overhead
367
6. **Update incrementally**: Migrate components one at a time rather than all at once
368
369
## Common Pitfalls
370
371
1. **Event handling differences**: Some events may behave differently between Svelte 4 and 5
372
2. **Lifecycle timing**: Component lifecycle may have subtle timing differences
373
3. **SSR compatibility**: Ensure legacy components work with server-side rendering
374
4. **Bundle size**: Legacy compatibility adds to bundle size
375
5. **Type compatibility**: TypeScript types may need adjustment for legacy components
376
377
## Debugging Legacy Components
378
379
```typescript
380
import { createClassComponent } from "svelte/legacy";
381
import Component from "./Component.svelte";
382
383
const LegacyComponent = createClassComponent(Component);
384
385
const instance = new LegacyComponent({
386
target: document.body,
387
props: { debug: true }
388
});
389
390
// Access internal state for debugging
391
console.log("Component props:", instance.$$.props);
392
console.log("Component context:", instance.$$.ctx);
393
394
// Monitor prop changes
395
const originalSet = instance.$set;
396
instance.$set = function(props) {
397
console.log("Legacy $set called with:", props);
398
return originalSet.call(this, props);
399
};
400
401
// Monitor events
402
const originalOn = instance.$on;
403
instance.$on = function(event, callback) {
404
console.log("Legacy $on registered for:", event);
405
return originalOn.call(this, event, callback);
406
};
407
```