Claude vs Gemini vs Grok: Svelte

Prompt
svelte 5 tutorial
ClaudeAnthropic
svelte 5 tutorial

Svelte 5 Tutorial

Svelte 5 introduces significant changes with the new runes system. Here's a comprehensive tutorial to get you started.

Table of Contents



What's New in Svelte 5 {#whats-new}


  • Runes: New reactive system replacing let, $:, and stores

  • Better TypeScript support

  • Improved performance

  • Simplified mental model

  • Enhanced developer experience


Installation {#installation}

# Create a new Svelte 5 project
npm create svelte@latest my-app
cd my-app
npm install
npm run dev

Basic Concepts {#basic-concepts}

Simple Component

<!-- App.svelte -->
<script>
import { state } from 'svelte/reactivity';

let name = state('World');
</script>

<h1>Hello {name.value}!</h1>
<input bind:value={name.value} />

Runes System {#runes-system}

Runes are the new reactive primitives in Svelte 5.

$state

Creates reactive state:

<script>
let count = $state(0);
let user = $state({
name: 'John',
age: 30
});
</script>

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

<p>User: {user.name}, Age: {user.age}</p>
<button onclick={() => user.age++}>
Increase Age
</button>

$derived

Creates computed values:

<script>
let count = $state(0);
let doubled = $derived(count * 2);
let message = $derived(`Count is ${count}`);
</script>

<p>Count: {count}</p>
<p>Doubled: {doubled}</p>
<p>{message}</p>
<button onclick={() => count++}>Increment</button>

$effect

Handles side effects:

<script>
let count = $state(0);

$effect(() => {
console.log(`Count changed to: ${count}`);

// Cleanup function (optional)
return () => {
console.log('Cleaning up effect');
};
});
</script>

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

$props

Handles component properties:

<!-- Child.svelte -->
<script>
let { title, count = 0, onClick } = $props();
</script>

<div>
<h2>{title}</h2>
<p>Count: {count}</p>
<button {onclick}>Click me</button>
</div>

<!-- Parent.svelte -->
<script>
import Child from './Child.svelte';

let count = $state(0);

function handleClick() {
count++;
}
</script>

<Child
title="My Component"
{count}
onClick={handleClick}
/>

Components {#components}

Component Communication

```svelte

19:54
GeminiGoogle
svelte 5 tutorial

Svelte 5: A Comprehensive Tutorial (with examples)

Svelte 5, also known as the "Runes" release, brings a significant paradigm shift to Svelte development. It introduces a new way to manage state and reactivity, based on runes, which are special symbols that attach behaviors to variables. This tutorial covers the core concepts and practical applications of Svelte 5.

Why Runes?

Runes provide:

  • Explicit reactivity: You explicitly mark variables that should be reactive, making code easier to understand and debug.

  • Fine-grained control: You have more control over when and how updates happen.

  • Improved performance: Svelte can optimize reactivity more effectively with explicit signals.

  • Better tooling: The explicit nature of runes enables better IDE support and linting.


Prerequisites:
  • Basic understanding of HTML, CSS, and JavaScript.

  • Node.js and npm (or a similar package manager) installed.


Setup:
  • Create a Svelte project:


npm create svelte@latest my-svelte-app
cd my-svelte-app
npm install
npm run dev

Choose the "skeleton project" option.

  • Update Svelte and Vite:


npm install svelte@next vite@next

  • Configure svelte.config.js:


Open svelte.config.js and ensure the kit config includes compilerOptions: { runes: true }. This enables rune support.

import adapter from '@sveltejs/adapter-auto';
import { vitePreprocess } from '@sveltejs/vite-plugin-svelte';

/** @type {import('@sveltejs/kit').Config} */
const config = {
kit: {
adapter: adapter(),
// Override http methods in the Todo list example
methodOverride: {
allowed: ['PATCH', 'DELETE']
}
},
preprocess: [vitePreprocess()],
compilerOptions: {
runes: true
}
};

export default config;

Core Concepts: Runes

Svelte 5 introduces several runes. Here are the key ones:

  • $ (Dollar Sign): This is the most fundamental rune. It's used to create reactive variables. When the value of a reactive variable changes, Svelte automatically updates the parts of the component that depend on it.

  • $derived: Creates derived signals. Derived signals are automatically updated when their dependencies (other signals) change. Think of them as computed properties.

  • $effect: Runs a function whenever its dependencies change. Useful for side effects like logging, DOM manipulation, or fetching data.

  • $state: (Less frequently used directly in components, mainly for libraries) Declares a variable as stateful, allowing it to be passed to components using bind: or let:.

  • $const: Declares a variable whose value should not be changed after initialization. (Note: While it prevents reassignment, the underlying value could still change if it's an object or array.)

  • $inspect: A debugging tool. Prints the current value of a signal to the console whenever it changes.


Examples:

Let's create a simple counter component using runes:

src/routes/+page.svelte:

<script>
import { $state } from '@sveltejs/svelte';

let count = $state(0);

function increment() {
count.set(count.get() + 1);
}

function decrement() {
count.set(count.get() - 1);
}
</script>

<h1>Counter: {count.get()}</h1>

<button on:click={increment}>Increment</button>
<button on:click={decrement}>Decrement</button>

Explanation:

  • import { $state } from '@sveltejs/svelte';: Imports the $state rune. This rune is provided by the Svelte runtime library.

  • let count = $state(0);: Declares a reactive variable named count initialized to 0. $state takes the initial value as an argument. Critically, count is now an object with get() and set() methods.

  • Counter: {count.get()}

    : Displays the current value of count. Because count is a state variable we access it using its get method

  • count.set(count.get() + 1);: Increments the value of count by 1. The .set() method triggers reactivity. Svelte knows to update the component because count is a reactive variable.


Derived Signals:

<script>
import { $state, $derived } from '@sveltejs/svelte';

let count = $state(0);
let doubled = $derived(count.get() * 2);

function increment() {
count.set(count.get() + 1);
}
</script>

<h1>Counter: {count.get()}</h1>
<h2>Doubled: {doubled.get()}</h2>

<button on:click={increment}>Increment</button>

Explanation:

  • **let doubled = $derived(count.get() * 2);**: Creates a derived signal called doubled. Its value is calculated as count * 2. Whenever count changes, doubled is automatically updated.


Effects:

<script>
import { $state, $effect } from '@sveltejs/svelte';

let count = $state(0);

$effect(() => {
console.log("Count changed to:", count.get());
document.title = `Count: ${count.get()}`; // Example DOM manipulation
});

function increment() {
count.set(count.get() + 1);
}
</script>

<h1>Counter: {count.get()}</h1>
<button on:click={increment}>Increment</button>

Explanation:

  • $effect(() => { ... });: Creates an effect. The function inside $effect will run whenever count changes. In this example, it logs the new value of count to the console and updates the page title.


Binding and Props (Simplified):

<!-- Parent Component (Parent.svelte) -->
<script>
import Child from './Child.svelte';
import { $state } from '@sveltejs/svelte';

let message = $state("Hello from Parent!");
let counter = $state(0);

function incrementParent() {
counter.set(counter.get() + 1);
}
</script>

<h1>Parent Component</h1>
<p>Message: {message.get()}</p>
<p>Parent Counter: {counter.get()}</p>
<button on:click={incrementParent}>Increment Parent</button>

<Child boundMessage={message} myCounter={counter} />

<!-- Child Component (Child.svelte) -->
<script>
import { $state, $effect } from '@sveltejs/svelte';

//Props are state variables, and are auto declared for runes
export let boundMessage;
export let myCounter;

let localCounter = $state(0);

$effect(() => {
console.log('Message received in Child: ', boundMessage.get());
})
function incrementChild() {
localCounter.set(localCounter.get() + 1);
}
</script>

<h2>Child Component</h2>
<p>Bound Message: {boundMessage.get()}</p>
<p>My Counter (from parent): {myCounter.get()}</p>
<p>Child Local Counter: {localCounter.get()}</p>
<button on:click={incrementChild}>Increment Child</button>


  • In the Parent Component, we declare message and counter as reactive state variables with $state().

  • We pass these signals to the child component Child via props boundMessage and myCounter.

  • In the Child.svelte the props are declared as standard svelte export let variables. Because Svelte knows that the props were passed as runes it will automatically handle reactivity

  • We can access the values inside of the child using the get() method.


Common Patterns and Best Practices:
  • Use $state sparingly. Avoid overusing $state. Use it only for values that need to be truly reactive. For simple variables that don't need to trigger updates, use regular let declarations.

  • Use $derived for computed values. Whenever you have a value that depends on other reactive values, use $derived to ensure it's automatically updated.

  • Effects for side effects. Use $effect only for side effects like DOM manipulation, logging, or fetching data. Avoid using $effect for updating state, as it can lead to infinite loops.

  • $const for immutability (with caveats). Use $const to declare constants that shouldn't be reassigned. Be aware that if the "constant" is an object or array, its contents can still be modified.

  • Use .set for modifying reactive variables. Always use the .set() method to update reactive variables created with $state. Direct assignment (e.g., count = newValue;) will not trigger reactivity.

  • Avoid complex logic in $derived. Keep the logic inside $derived functions simple and pure. Complex logic is better placed in separate functions.

  • Be mindful of dependencies in $effect. Svelte automatically tracks the dependencies of $effect functions. However, it's a good practice to explicitly list dependencies using bind: or let:, especially for complex components.


Example: Fetching Data

<script>
import { $state, $effect } from '@sveltejs/svelte';

let todos = $state([]);
let loading = $state(true);
let error = $state(null);

$effect(async () => {
loading.set(true);
error.set(null);

try {
const response = await fetch('https://jsonplaceholder.typicode.com/todos');
if (!response.ok) {
throw new Error(`HTTP error! Status: ${response.status}`);
}
const data = await response.json();
todos.set(data);
} catch (e) {
error.set(e.message);
} finally {
loading.set(false);
}
});
</script>

{#if loading.get()}
<p>Loading...</p>
{:else if error.get()}
<p>Error: {error.get()}</p>
{:else}
<ul>
{#each todos.get() as todo}
<li>{todo.title}</li>
{/each}
</ul>
{/if}

Key Takeaways:

  • Svelte 5's runes offer a more explicit and controllable way to manage reactivity.

  • $ (with $state and $derived) and $effect are the most commonly used runes.

  • Use runes judiciously, focusing on truly reactive values.

  • Understand the .get() and .set() methods for accessing and modifying rune based state.

  • Runes enable better performance and tooling.


Further Learning:
  • Svelte Documentation: The official Svelte documentation is the best resource for in-depth information: https://svelte.dev/ (Pay close attention to the "5.0" or "next" documentation).

  • Svelte Discord: Join the Svelte Discord community for help and discussions: https://svelte.dev/chat

  • Svelte Examples: Explore real-world examples of Svelte 5 applications to learn best practices.


This tutorial provides a solid foundation for understanding Svelte 5's runes. Experiment, build projects, and explore the documentation to master this powerful new approach to Svelte development. Remember to keep checking the official Svelte documentation for updates as Svelte 5 continues to evolve.
19:54
GrokxAI
svelte 5 tutorial

Svelte 5 is the latest iteration of the Svelte framework, introducing significant updates and improvements over previous versions. As of now, Svelte 5 is still in preview, and its features may evolve before the final release. This tutorial will cover the basics of Svelte 5, assuming you have a fundamental understanding of web development and JavaScript. If Svelte 5 has been officially released or updated since my last knowledge update (October 2023), I recommend checking the official Svelte documentation for the latest information.

What’s New in Svelte 5?


Svelte 5 introduces several key features and improvements, including:
  • Runes: A new reactivity system that replaces the old reactive statements ($:) with more explicit and powerful primitives like $state, $derived, and $effect.

  • Improved Performance: Further optimizations to the compiler for faster updates and smaller bundles.

  • Better TypeScript Integration: Enhanced support for TypeScript with better type inference.

  • Snippets: A new way to define reusable UI components as snippets.

  • Refined Reactivity Model: More intuitive and explicit control over reactivity.


This tutorial will walk you through setting up a Svelte 5 project, using Runes for reactivity, and building a simple application.


Step 1: Setting Up a Svelte 5 Project


  • Install Node.js:

Make sure you have Node.js (version 18 or higher) installed on your machine. You can download it from nodejs.org.
  • Create a New Svelte Project:

Use the degit tool or the official SvelteKit CLI to scaffold a new Svelte 5 project. Since Svelte 5 is tied to SvelteKit for project initialization, we’ll use SvelteKit.

Run the following command to create a new project:

npm create vite@latest my-svelte-app -- --template svelte

  • Select "Svelte" as the framework.

  • Choose whether to use TypeScript (recommended for better type safety).

  • Follow the prompts to configure additional options like ESLint or Prettier.

  • Navigate to the Project Directory:

cd my-svelte-app

  • Install Dependencies:

npm install

  • Start the Development Server:

npm run dev

Open your browser and navigate to http://localhost:5173 (or the port specified in the terminal) to see the default Svelte starter app.


Step 2: Understanding Svelte 5 Runes


Runes are the new reactivity system in Svelte 5, replacing the $: syntax for reactive statements. They make reactivity more explicit and easier to reason about. The primary runes are $state, $derived, and $effect.

Example: Using $state for Reactive Variables


Create a new component in src/routes/+page.svelte and replace its content with the following:

<script>
import { $state } from 'svelte';

// Declare a reactive state variable using $state
let count = $state(0);

function increment() {
count += 1; // Directly update the state
}
</script>

<h1>Counter: {count}</h1>
<button on:click={increment}>Increment</button>


  • $state declares a reactive variable. When count changes, the DOM automatically updates to reflect the new value.

  • Unlike Svelte 4, you no longer need to use $: for reactivity; $state handles it explicitly.


Example: Using $derived for Computed Values


$derived is used to create values that depend on other reactive states.

<script>
import { $state, $derived } from 'svelte';

let count = $state(0);
let doubled = $derived(count * 2); // Derived value updates when count changes

function increment() {
count += 1;
}
</script>

<h1>Counter: {count}</h1>
<h2>Doubled: {doubled}</h2>
<button on:click={increment}>Increment</button>


  • $derived automatically recomputes doubled whenever count changes.


Example: Using $effect for Side Effects


$effect lets you run side effects (like logging or fetching data) when reactive values change.

<script>
import { $state, $effect } from 'svelte';

let count = $state(0);

$effect(() => {
console.log(`Count changed to: ${count}`);
});

function increment() {
count += 1;
}
</script>

<h1>Counter: {count}</h1>
<button on:click={increment}>Increment</button>


  • $effect runs whenever any reactive dependency (like count) changes.



Step 3: Building a Simple Todo App with Svelte 5


Let’s create a small Todo application to demonstrate Svelte 5’s features in action.
  • Update src/routes/+page.svelte with the following code:


<script>
import { $state } from 'svelte';

// Reactive state for todos and input
let todos = $state([]);
let newTodo = $state('');

function addTodo() {
if (newTodo.trim()) {
todos = [...todos, { id: todos.length + 1, text: newTodo, done: false }];
newTodo = ''; // Reset input
}
}

function toggleTodo(id) {
todos = todos.map((todo) =>
todo.id === id ? { ...todo, done: !todo.done } : todo
);
}
</script>

<h1>Todo List</h1>

<input
type="text"
bind:value={newTodo}
placeholder="Add a new todo"
on:keydown={(e) => e.key === 'Enter' && addTodo()}
/>
<button on:click={addTodo}>Add</button>

<ul>
{#each todos as todo}
<li style="text-decoration: {todo.done ? 'line-through' : 'none'}">
{todo.text}
<button on:click={() => toggleTodo(todo.id)}>
{todo.done ? 'Undo' : 'Complete'}
</button>
</li>
{:else}
<p>No todos yet!</p>
{/each}
</ul>


  • Run the app with npm run dev and interact with the Todo list by adding and toggling tasks.

  • The todos array is reactive thanks to $state, so the UI updates automatically when items are added or modified.

  • The #each directive loops over the todos array to render the list.



Step 4: Using Snippets in Svelte 5


Svelte 5 introduces "snippets," which are reusable blocks of UI code. They’re similar to components but lighter and more focused on rendering markup.

Example of a snippet in src/routes/+page.svelte:

<script>
import { $state } from 'svelte';

let name = $state('World');

// Define a reusable snippet
$: greeting = `<h2>Hello, {name}!</h2>`;
</script>

<!-- Use the snippet -->
{@render greeting}


  • Snippets allow you to define reusable UI logic without creating a full component.



Step 5: Building and Deploying


  • Build the app for production:

npm run build

  • Preview the production build locally:

npm run preview

  • Deploy to a hosting service like Vercel, Netlify, or GitHub Pages by following their respective guides for SvelteKit apps.



Additional Tips


  • TypeScript Support: If you chose TypeScript during setup, ensure your editor (e.g., VS Code) has the Svelte extension installed for proper type checking.

  • SvelteKit Features: Explore SvelteKit’s features like file-system-based routing, server-side rendering (SSR), and static site generation (SSG).

  • Community Resources: Join the Svelte Discord or follow the official Svelte blog for updates on Svelte 5.

  • Official Docs: The Svelte documentation and SvelteKit docs are excellent resources for learning more about specific features.



Conclusion


Svelte 5 brings exciting changes with Runes, snippets, and improved performance, making it an even more powerful framework for building web applications. This tutorial covered the basics of setting up a project, using the new reactivity system, and building a simple app. As Svelte 5 evolves, keep an eye on the official documentation and community for updates and best practices.

If you have specific questions or want to dive deeper into a particular feature (e.g., stores, animations, or SvelteKit routing), let me know!

19:54

Analysis

This comparison demonstrates the different approaches each AI model takes when responding to the same prompt. Here are the key differences observed:

Response Characteristics

Claude: Provides a direct response with 33 sentences.

Gemini: Provides a direct response with 174 sentences.

Grok: Provides a direct response with 93 sentences.

Key Takeaways

  • Each model brings unique strengths to this type of query
  • Response styles vary significantly between models
  • Consider your specific use case when choosing between these models

Try This Comparison Yourself

Want to test these models with your own prompts? Visit SNEOS.com to compare AI responses side-by-side in real-time.


This comparison was generated using the SNEOS AI Comparison ToolPublished: October 01, 2025 | Models: Claude, Gemini, Grok