Svelte has evolved significantly, becoming one of the most efficient frameworks for building modern web applications. In 2025, the framework has introduced several powerful features that developers should master. This comprehensive guide will walk you through both essential and advanced features with practical examples.
1. Advanced Reactive Declarations
Reactive declarations in Svelte are more powerful than simple computed values. They can handle complex logic and side effects.
<script>
let count = 0;
let items = [];
// Simple reactive declaration
$: doubled = count * 2;
// Complex reactive declaration with conditions
$: if (count > 10) {
console.log('Count is getting high!');
items = [...items, count];
}
// Multiple statements
$: {
console.log(`Count changed to ${count}`);
localStorage.setItem('count', count);
}
</script>
<button on:click={() => count++}>Increment ({count})</button>
<ul>
{#each items as item}
<li>{item}</li>
{/each}
</ul>
2. Runes Mode (New in Svelte 5)
Runes represent a new way to handle reactivity in Svelte, offering more explicit and flexible state management. They’re marked with a ’$’ prefix and provide fine-grained control over reactivity.
<script>
let count = $state(0);
let doubled = $derived(count * 2);
// Effect rune
$effect(() => {
console.log(`Count changed to: ${count}`);
});
// Props with runes
let name = $props.name;
// Computed values
let fullName = $derived(`${name} Smith`);
// Batched updates
function incrementTwice() {
$batch(() => {
count++; // These updates will be batched
count++; // into a single re-render
});
}
</script>
<button on:click={incrementTwice}>
Increment Twice ({count})
</button>
<p>Doubled: {doubled}</p>
<p>Name: {fullName}</p>
Advanced Runes Patterns
<script>
// Custom state management with runes
function createCounter() {
let count = $state(0);
return {
get value() { return count; },
increment: () => count++,
decrement: () => count--
};
}
const counter = createCounter();
// Lifecycle runes
$effect.pre(() => {
// Runs before DOM updates
console.log('Preparing update...');
});
$effect.root(() => {
// Creates an isolated reactive scope
const localState = $state(0);
});
</script>
<button on:click={counter.increment}>
Count: {counter.value}
</button>
3. Advanced Store Management
Svelte’s store system offers sophisticated state management capabilities, including derived stores and custom stores.
// stores/advanced-store.ts
import { writable, derived } from 'svelte/store';
// Custom store with additional functionality
function createCounterStore() {
const { subscribe, set, update } = writable(0);
return {
subscribe,
increment: () => update(n => n + 1),
decrement: () => update(n => n - 1),
reset: () => set(0)
};
}
export const count = createCounterStore();
export const doubled = derived(count, $count => $count * 2);
export const isEven = derived(count, $count => $count % 2 === 0);
4. SvelteKit 2.0 Features
SvelteKit has evolved with powerful server-side features and better routing capabilities.
// routes/api/data/+server.ts
import { json } from '@sveltejs/kit';
import type { RequestHandler } from './$types';
export const GET: RequestHandler = async ({ url, params }) => {
const data = await fetchSomeData();
return json(data);
};
// routes/blog/[slug]/+page.ts
export const load = async ({ params }) => {
const post = await getPost(params.slug);
return { post };
};
5. Advanced TypeScript Integration
TypeScript support in Svelte has been enhanced with better type inference and generics support.
<script lang="ts">
interface User {
id: number;
name: string;
email: string;
}
type SortKey = keyof User;
let users: User[] = [];
let sortKey: SortKey = 'name';
function sortUsers(key: SortKey) {
users = users.sort((a, b) =>
a[key] < b[key] ? -1 : a[key] > b[key] ? 1 : 0
);
}
</script>
6. Advanced Animations and Transitions
Svelte’s animation system now supports complex choreographed animations and custom transitions.
<script>
import { fade, fly, crossfade } from 'svelte/transition';
import { elasticOut } from 'svelte/easing';
const [send, receive] = crossfade({
duration: 400,
easing: elasticOut
});
let items = [1, 2, 3];
</script>
{#each items as item (item)}
<div
in:receive={{key: item}}
out:send={{key: item}}
animate:flip
>
{item}
</div>
{/each}
7. Custom Stores with Persistence
Learn how to create stores that persist data across page reloads.
import { writable } from 'svelte/store';
function createPersistedStore<T>(key: string, initialValue: T) {
const storedValue = localStorage.getItem(key);
const store = writable(storedValue ? JSON.parse(storedValue) : initialValue);
store.subscribe(value => {
localStorage.setItem(key, JSON.stringify(value));
});
return store;
}
export const settings = createPersistedStore('app-settings', {
theme: 'light',
fontSize: 16
});
8. Actions and Use Directives
Actions provide a powerful way to add custom DOM behavior.
<script>
function longpress(node: HTMLElement, duration: number) {
let timer: ReturnType<typeof setTimeout>;
function handleMousedown() {
timer = setTimeout(() => {
node.dispatchEvent(new CustomEvent('longpress'));
}, duration);
}
function handleMouseup() {
clearTimeout(timer);
}
node.addEventListener('mousedown', handleMousedown);
node.addEventListener('mouseup', handleMouseup);
return {
destroy() {
node.removeEventListener('mousedown', handleMousedown);
node.removeEventListener('mouseup', handleMouseup);
}
};
}
</script>
<button use:longpress={1000} on:longpress={() => console.log('long pressed!')}>
Hold me
</button>
Conclusion
Mastering these advanced Svelte features will significantly improve your ability to build sophisticated, performant web applications. The framework’s evolution continues to prioritize developer experience while maintaining its core principles of simplicity and efficiency. Keep experimenting with these features and combining them in creative ways to build better applications.