Not found at this URL
https://svelte.dev/docs/svelte/llms-full.txt ↗- Discovery
- Conventional sibling path checked
- HTTP response
- 404 · text/html
Developer tools · llms.txt file breakdown
Overview organizes Svelte documentation around Alternatives to SvelteKit, Editor tooling, Getting help, `<script>` and 363 more sections.
The actual file
The saved llms.txt text, displayed as source. The file belongs to its publisher; the live endpoint may change.
Showing the first 18000 characters. Load the complete file to read the remainder.
<SYSTEM>This is the developer documentation for Svelte.</SYSTEM>
# Overview
Svelte is a framework for building user interfaces on the web. It uses a compiler to turn declarative components written in HTML, CSS and JavaScript...
```svelte
<!--- file: App.svelte --->
<script>
function greet() {
alert('Welcome to Svelte!');
}
</script>
<button onclick={greet}>click me</button>
<style>
button {
font-size: 2em;
}
</style>
```
...into lean, tightly optimized JavaScript.
You can use it to build anything on the web, from standalone components to ambitious full stack apps (using Svelte's companion application framework, [SvelteKit](../kit)) and everything in between.
These pages serve as reference documentation. If you're new to Svelte, we recommend starting with the [interactive tutorial](/tutorial) and coming back here when you have questions.
You can also try Svelte online in the playground.
# Getting started
We recommend using [SvelteKit](../kit), which lets you [build almost anything](../kit/project-types). It's the official application framework from the Svelte team and powered by [Vite](https://vite.dev/). Create a new project with:
```sh
npx sv create myapp
cd myapp
npm install
npm run dev
```
Don't worry if you don't know Svelte yet! You can ignore all the nice features SvelteKit brings on top for now and dive into it later.
## Alternatives to SvelteKit
You can also use Svelte directly with Vite via [vite-plugin-svelte](https://github.com/sveltejs/vite-plugin-svelte) by running `npm create vite@latest` and selecting the `svelte` option (or, if working with an existing project, adding the plugin to your `vite.config.js` file). With this, `npm run build` will generate HTML, JS, and CSS files inside the `dist` directory. In most cases, you will probably need to [choose a routing library](/packages#routing) as well.
>[!NOTE] Vite is often used in standalone mode to build [single page apps (SPAs)](../kit/glossary#SPA), which you can also [build with SvelteKit](../kit/single-page-apps).
There are also [plugins for other bundlers](/packages#bundler-plugins), but we recommend Vite.
## Editor tooling
The Svelte team maintains a [VS Code extension](https://marketplace.visualstudio.com/items?itemName=svelte.svelte-vscode), and there are integrations with various other [editors](https://sveltesociety.dev/collection/editor-support-c85c080efc292a34) and tools as well.
You can also check your code from the command line using [`npx sv check`](https://svelte.dev/docs/cli/sv-check).
## Getting help
Don't be shy about asking for help in the [Discord chatroom](/chat)! You can also find answers on [Stack Overflow](https://stackoverflow.com/questions/tagged/svelte).
# .svelte files
Components are the building blocks of Svelte applications. They are written into `.svelte` files, using a superset of HTML.
All three sections — script, styles and markup — are optional.
<!-- prettier-ignore -->
```svelte
/// file: MyComponent.svelte
<script module>
// module-level logic goes here
// (you will rarely use this)
</script>
<script>
// instance-level logic goes here
</script>
<!-- markup (zero or more items) goes here -->
<style>
/* styles go here */
</style>
```
## `<script>`
A `<script>` block contains JavaScript (or TypeScript, when adding the `lang="ts"` attribute) that runs when a component instance is created. Variables declared (or imported) at the top level can be referenced in the component's markup.
In addition to normal JavaScript, you can use _runes_ to declare [component props]($props) and add reactivity to your component. Runes are covered in the next section.
<!-- TODO describe behaviour of `export` -->
## `<script module>`
A `<script>` tag with a `module` attribute runs once when the module first evaluates, rather than for each component instance. Variables declared in this block can be referenced elsewhere in the component, but not vice versa.
```svelte
<script module>
let total = 0;
</script>
<script>
total += 1;
console.log(`instantiated ${total} times`);
</script>
```
You can `export` bindings from this block, and they will become exports of the compiled module. You cannot `export default`, since the default export is the component itself.
> [!NOTE] If you are using TypeScript and import such exports from a `module` block into a `.ts` file, make sure to have your editor setup so that TypeScript knows about them. This is the case for our VS Code extension and the IntelliJ plugin, but in other cases you might need to setup our [TypeScript editor plugin](https://www.npmjs.com/package/typescript-svelte-plugin).
> [!LEGACY]
> In Svelte 4, this script tag was created using `<script context="module">`
## `<style>`
CSS inside a `<style>` block will be scoped to that component.
```svelte
<style>
p {
/* this will only affect <p> elements in this component */
color: burlywood;
}
</style>
```
For more information, head to the section on [styling](scoped-styles).
# .svelte.js and .svelte.ts files
Besides `.svelte` files, Svelte also operates on `.svelte.js` and `.svelte.ts` files.
These behave like any other `.js` or `.ts` module, except that you can use runes. This is useful for creating reusable reactive logic, or sharing reactive state across your app (though note that you [cannot export reassigned state]($state#Passing-state-across-modules)).
> [!LEGACY]
> This is a concept that didn't exist prior to Svelte 5
# What are runes?
> [!NOTE] **rune** /ruːn/ _noun_
>
> A letter or mark used as a mystical or magic symbol.
Runes are symbols that you use in `.svelte` and `.svelte.js`/`.svelte.ts` files to control the Svelte compiler. If you think of Svelte as a language, runes are part of the syntax — they are _keywords_.
Runes have a `$` prefix and look like functions:
```js
let message = $state('hello');
```
They differ from normal JavaScript functions in important ways, however:
- You don't need to import them — they are part of the language
- They're not values — you can't assign them to a variable or pass them as arguments to a function
- Just like JavaScript keywords, they are only valid in certain positions (the compiler will help you if you put them in the wrong place)
> [!LEGACY]
> Runes didn't exist prior to Svelte 5.
# $state
The `$state` rune allows you to create _reactive state_, which means that your UI _reacts_ when it changes.
```svelte
<script>
let count = $state(0);
</script>
<button onclick={() => count++}>
clicks: {count}
</button>
```
Unlike other frameworks you may have encountered, there is no API for interacting with state — `count` is just a number, rather than an object or a function, and you can update it like you would update any other variable.
### Deep state
If `$state` is used with an array or a simple object, the result is a deeply reactive _state proxy_. [Proxies](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Proxy) allow Svelte to run code when you read or write properties, including via methods like `array.push(...)`, triggering granular updates.
State is proxified recursively until Svelte finds something other than an array or simple object (like a class or an object created with `Object.create`). In a case like this...
```js
let todos = $state([
{
done: false,
text: 'add more todos'
}
]);
```
...modifying an individual todo's property will trigger updates to anything in your UI that depends on that specific property:
```js
let todos = [{ done: false, text: 'add more todos' }];
// ---cut---
todos[0].done = !todos[0].done;
```
If you push a new object to the array, it will also be proxified:
```js
let todos = [{ done: false, text: 'add more todos' }];
// ---cut---
todos.push({
done: false,
text: 'eat lunch'
});
```
> [!NOTE] When you update properties of proxies, the original object is _not_ mutated. If you need to use your own proxy handlers in a state proxy, you should wrap the object _after_ wrapping it in `$state`.
Note that if you destructure a reactive value, the references are not reactive — as in normal JavaScript, they are evaluated at the point of destructuring:
```js
let todos = [{ done: false, text: 'add more todos' }];
// ---cut---
let { done, text } = todos[0];
// this will not affect the value of `done`
todos[0].done = !todos[0].done;
```
### Classes
Class instances are not proxied. Instead, you can use `$state` in class fields (whether public or private), or as the first assignment to a property immediately inside the `constructor`:
```js
// @errors: 7006 2554
class Todo {
done = $state(false);
constructor(text) {
this.text = $state(text);
}
reset() {
this.text = '';
this.done = false;
}
}
```
> [!NOTE] The compiler transforms `done` and `text` into `get`/`set` methods on the class prototype referencing private fields. This means the properties are not enumerable.
When calling methods in JavaScript, the value of [`this`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/this) matters. This won't work, because `this` inside the `reset` method will be the `<button>` rather than the `Todo`:
```svelte
<button onclick={todo.reset}>
reset
</button>
```
You can either use an inline function...
```svelte
<button onclick=+++{() => todo.reset()}>+++
reset
</button>
```
...or use an arrow function in the class definition:
```js
// @errors: 7006 2554
class Todo {
done = $state(false);
constructor(text) {
this.text = $state(text);
}
+++reset = () => {+++
this.text = '';
this.done = false;
}
}
```
### Built-in classes
Svelte provides reactive implementations of built-in classes like `Set`, `Map`, `Date` and `URL` that can be imported from [`svelte/reactivity`](svelte-reactivity).
## `$state.raw`
In cases where you don't want objects and arrays to be deeply reactive you can use `$state.raw`.
State declared with `$state.raw` cannot be mutated; it can only be _reassigned_. In other words, rather than assigning to a property of an object, or using an array method like `push`, replace the object or array altogether if you'd like to update it:
```js
let person = $state.raw({
name: 'Heraclitus',
age: 49
});
// this will have no effect
person.age += 1;
// this will work, because we're creating a new person
person = {
name: 'Heraclitus',
age: 50
};
```
This can improve performance with large arrays and objects that you weren't planning to mutate anyway, since it avoids the cost of making them reactive. Note that raw state can _contain_ reactive state (for example, a raw array of reactive objects).
As with `$state`, you can declare class fields using `$state.raw`.
## `$state.snapshot`
To take a static snapshot of a deeply reactive `$state` proxy, use `$state.snapshot`:
```svelte
<script>
let counter = $state({ count: 0 });
function onclick() {
// Will log `{ count: ... }` rather than `Proxy { ... }`
console.log($state.snapshot(counter));
}
</script>
```
This is handy when you want to pass some state to an external library or API that doesn't expect a proxy, such as `structuredClone`.
If a value has a `toJSON` method, the snapshot will clone the value returned from `toJSON` instead of the original object.
## `$state.eager`
When state changes, it may not be reflected in the UI immediately if it is used by an `await` expression, because [updates are synchronized](await-expressions#Synchronized-updates).
In some cases, you may want to update the UI as soon as the state changes. For example, you might want to update a navigation bar when the user clicks on a link, so that they get visual feedback while waiting for the new page to load. To do this, use `$state.eager(value)`:
```svelte
<nav>
<a href="/" aria-current={$state.eager(pathname) === '/' ? 'page' : null}>home</a>
<a href="/about" aria-current={$state.eager(pathname) === '/about' ? 'page' : null}>about</a>
</nav>
```
Use this feature sparingly, and only to provide feedback in response to user action — in general, allowing Svelte to coordinate updates will provide a better user experience.
## Passing state into functions
JavaScript is a _pass-by-value_ language — when you call a function, the arguments are the _values_ rather than the _variables_. In other words:
```js
/// file: index.js
// @filename: index.js
// ---cut---
/**
* @param {number} a
* @param {number} b
*/
function add(a, b) {
return a + b;
}
let a = 1;
let b = 2;
let total = add(a, b);
console.log(total); // 3
a = 3;
b = 4;
console.log(total); // still 3!
```
If `add` wanted to have access to the _current_ values of `a` and `b`, and to return the current `total` value, you would need to use functions instead:
```js
/// file: index.js
// @filename: index.js
// ---cut---
/**
* @param {() => number} getA
* @param {() => number} getB
*/
function add(+++getA, getB+++) {
return +++() => getA() + getB()+++;
}
let a = 1;
let b = 2;
let total = add+++(() => a, () => b)+++;
console.log(+++total()+++); // 3
a = 3;
b = 4;
console.log(+++total()+++); // 7
```
State in Svelte is no different — when you reference something declared with the `$state` rune...
```js
let a = +++$state(1)+++;
let b = +++$state(2)+++;
```
...you're accessing its _current value_.
Note that 'functions' is broad — it encompasses properties of proxies and [`get`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/get)/[`set`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/set) properties...
```js
/// file: index.js
// @filename: index.js
// ---cut---
/**
* @param {{ a: number, b: number }} input
*/
function add(input) {
return {
get value() {
return input.a + input.b;
}
};
}
let input = $state({ a: 1, b: 2 });
let total = add(input);
console.log(total.value); // 3
input.a = 3;
input.b = 4;
console.log(total.value); // 7
```
...though if you find yourself writing code like that, consider using [classes](#Classes) instead.
## Passing state across modules
You can declare state in `.svelte.js` and `.svelte.ts` files, but you can only _export_ that state if it's not directly reassigned. In other words you can't do this:
```js
/// file: state.svelte.js
export let count = $state(0);
export function increment() {
count += 1;
}
```
That's because every reference to `count` is transformed by the Svelte compiler — the code above is roughly equivalent to this:
```js
/// file: state.svelte.js (compiler output)
// @filename: index.ts
interface Signal<T> {
value: T;
}
interface Svelte {
state<T>(value?: T): Signal<T>;
get<T>(source: Signal<T>): T;
set<T>(source: Signal<T>, value: T): void;
}
declare const $: Svelte;
// ---cut---
export let count = $.state(0);
export function increment() {
$.set(count, $.get(count) + 1);
}
```
> [!NOTE] You can see the code Svelte generates by clicking the 'JS Output' tab in the [playground](/playground).
Since the compiler only operates on one file at a time, if another file imports `count` Svelte doesn't know that it needs to wrap each reference in `$.get` and `$.set`:
```js
// @filename: state.svelte.js
export let count = 0;
// @filename: index.js
// ---cut---
import { count } from './state.svelte.js';
console.log(typeof count); // 'object', not 'number'
```
This leaves you with two options for sharing state between modules — either don't reassign it...
```js
// This is allowed — since we're updating
// `counter.count` rather than `counter`,
// Svelte doesn't wrap it in `$.state`
export const counter = $state({
count: 0
});
export function increment() {
counter.count += 1;
}
```
...or don't directly export it:
```js
let count = $state(0);
export function getCount() {
return count;
}
export function increment() {
count += 1;
}
```
# $derived
Derived state is declared with the `$derived` rune:
```svelte
<script>
let count = $state(0);
let doubled = $derived(count * 2);
</script>
<button onclick={() => count++}>
{doubled}
</button>
<p>{count} doubled is {doubled}</p>
```
The expression inside `$derived(...)` should be free of side-effects. Svelte will disallow state changes (e.g. `count++`) inside derived expressions.
As with `$state`, you can mark class fields as `$derived`.
> [!NOTE] Code in Svelte components is only executed once at creation. Without the `$derived` rune, `doubled` would maintain its original value even when `count` changes.
## `$derived.by`
Sometimes you need to create complex derivations that don't fit inside a short expression. In these cases, you can use `$derived.by` which accepts a function as its argument.
```svelte
<script>
let numbers = $state([1, 2, 3]);
let total = $derived.by(() => {
let total = 0;
for (const n of numbers) {
total += n;
}
return total;
});
</script>
<button onclick={() => numbers.push(numbers.length + 1)}>
{numbers.join(' + ')} = {total}
</button>
```
In essence, `$derived(expression)` is equivalent to `$derived.by(() => expression)`.
## Understanding dependencies
Anything read synchronously inside the `$derived` expression (or `$derived.by` function body) is considered a _dependency_ of the derived state. When the state changes, the derived will be marked as _dirty_ and recalculated when it is next read.
In addition, if an expression contains an [`await`](await-expressions), Svelte transforms it such that any state _after_ the `await` is also tracked — in other words, in a case like this...
```js
let a = Promise.resolve(1);
let b = 2;
// ---cut---
let total = $derived(await a + b);
```
...both `a` and `b` are tracked, even though `b` is only read once `a` has resolved, after the initial execution. (This does not apply to `await` in functions that are called by the expression, only the expression itself.)
To exempt a piece of state from being treated as a dependency, use [`untrack`](svelte#untrack).
## Overriding derived values
Derived expressions are recalculated when their dependencies change, but you can temporarily overridMeasured from the saved file
Size measures the captured UTF-8 text, not compressed transfer size. Tokens are counted with a named tokenizer; other models can count differently. Neither measure establishes context compatibility or answer quality.
Context architecture
367 H2 sections organize 436 parsed Markdown links. 2 links point to .md or .markdown paths; 193 link occurrences use another hostname. Linked destinations have not been recursively validated.
| H2 section | Links | UTF-8 bytes | Tokens |
|---|---|---|---|
| Alternatives to SvelteKitLine 46 | 5 | 739 | 191 |
| Editor toolingLine 54 | 3 | 385 | 97 |
| Getting helpLine 61 | 2 | 681 | 160 |
| `<script>`Line 90 | 1 | 454 | 101 |
| `<script module>`Line 98 | 1 | 1005 | 232 |
| `<style>`Line 120 | 5 | 5048 | 1281 |
| `$state.raw`Line 290 | 0 | 888 | 205 |
| `$state.snapshot`Line 316 | 0 | 543 | 133 |
| `$state.eager`Line 335 | 1 | 844 | 204 |
| Passing state into functionsLine 350 | 3 | 1854 | 566 |
| Passing state across modulesLine 437 | 1 | 2402 | 617 |
| `$derived.by`Line 540 | 0 | 552 | 145 |
| Understanding dependenciesLine 563 | 2 | 860 | 209 |
| Overriding derived valuesLine 580 | 0 | 818 | 208 |
| Deriveds and reactivityLine 609 | 1 | 485 | 128 |
| DestructuringLine 623 | 0 | 450 | 141 |
| H2 section | Links | UTF-8 bytes | Tokens |
|---|---|---|---|
| Update propagationLine 644 | 6 | 6810 | 1670 |
| `$effect.pre`Line 830 | 1 | 1062 | 279 |
| `$effect.tracking`Line 869 | 1 | 787 | 182 |
| `$effect.pending`Line 890 | 2 | 694 | 194 |
| `$effect.root`Line 918 | 0 | 418 | 97 |
| When not to use `$effect`Line 937 | 4 | 3458 | 904 |
| Fallback valuesLine 1075 | 1 | 325 | 80 |
| Renaming propsLine 1085 | 0 | 228 | 55 |
| Rest propsLine 1093 | 0 | 127 | 42 |
| Updating propsLine 1101 | 3 | 3024 | 763 |
| Type safetyLine 1222 | 3 | 1104 | 250 |
| `$props.id()`Line 1260 | 1 | 3340 | 798 |
| $inspect(...).withLine 1358 | 0 | 631 | 162 |
| $inspect.trace(...)Line 1379 | 3 | 1449 | 367 |
| TagsLine 1437 | 0 | 276 | 74 |
| Element attributesLine 1451 | 3 | 1421 | 350 |
| Component propsLine 1505 | 0 | 285 | 72 |
| Spread attributesLine 1515 | 0 | 381 | 93 |
| EventsLine 1525 | 2 | 2917 | 650 |
| Text expressionsLine 1581 | 4 | 1308 | 349 |
| CommentsLine 1611 | 2 | 2641 | 750 |
| Keyed each blocksLine 1732 | 0 | 1177 | 328 |
| Each blocks without an itemLine 1775 | 0 | 722 | 239 |
| Else blocksLine 1816 | 3 | 4079 | 1116 |
| Snippet scopeLine 1988 | 0 | 1256 | 350 |
| Passing snippets to componentsLine 2049 | 0 | 3707 | 1102 |
| Typing snippetsLine 2248 | 0 | 841 | 229 |
| Exporting snippetsLine 2286 | 0 | 682 | 186 |
| Programmatic snippetsLine 2316 | 1 | 144 | 31 |
| Snippets and slotsLine 2320 | 2 | 531 | 159 |
| Optional snippetsLine 2344 | 2 | 969 | 246 |
| StylingLine 2382 | 3 | 1288 | 339 |
| Attachment factoriesLine 2439 | 2 | 914 | 222 |
| Inline attachmentsLine 2471 | 0 | 503 | 136 |
| Conditional attachmentsLine 2494 | 0 | 165 | 38 |
| Passing attachments to componentsLine 2502 | 2 | 1132 | 282 |
| Controlling when attachments re-runLine 2548 | 1 | 660 | 198 |
| Creating attachments programmaticallyLine 2577 | 1 | 152 | 31 |
| Converting actions to attachmentsLine 2581 | 4 | 4237 | 1085 |
| Function bindingsLine 2721 | 1 | 502 | 140 |
| `<input bind:value>`Line 2744 | 0 | 1458 | 406 |
| `<input bind:checked>`Line 2800 | 0 | 680 | 178 |
| `<input bind:indeterminate>`Line 2826 | 1 | 451 | 118 |
| `<input bind:group>`Line 2849 | 0 | 1220 | 341 |
| `<input bind:files>`Line 2889 | 2 | 1184 | 284 |
| `<select bind:value>`Line 2911 | 0 | 1962 | 505 |
| `<audio>`Line 2968 | 12 | 1281 | 314 |
| `<video>`Line 2992 | 3 | 297 | 69 |
| `<img>`Line 2996 | 2 | 248 | 57 |
| `<details bind:open>`Line 3003 | 0 | 199 | 56 |
| `window` and `document`Line 3014 | 2 | 135 | 39 |
| Contenteditable bindingsLine 3018 | 4 | 674 | 156 |
| DimensionsLine 3034 | 8 | 1380 | 317 |
| bind:thisLine 3055 | 1 | 1093 | 264 |
| bind:_property_ for componentsLine 3099 | 2 | 2395 | 599 |
| TypingLine 3179 | 0 | 1472 | 393 |
| Local vs globalLine 3237 | 0 | 346 | 98 |
| Built-in transitionsLine 3251 | 1 | 112 | 24 |
| Transition parametersLine 3255 | 0 | 258 | 66 |
| AccessibilityLine 3267 | 2 | 457 | 99 |
| Custom transition functionsLine 3273 | 2 | 3081 | 825 |
| Transition eventsLine 3368 | 4 | 1772 | 464 |
| Animation ParametersLine 3425 | 0 | 277 | 70 |
| Custom animation functionsLine 3437 | 2 | 4018 | 1121 |
287 additional H2 sections are present in the source Markdown. This table previews the first 80 sections.
Link counts exclude parsed fenced and inline code and resolve relative destinations against the final endpoint. Section sizes cover the text below each H2 until the next H2.
Embedded material
Embedded example text and links to further documentation are counted separately. A code block does not establish that a sample runs or that an authentication flow succeeds.
Source line 40 · sh
npm installSource line 5444 · sh
npm install -D vitestSource line 5629 · sh
npm install -D jsdomPublisher prioritization
No H2 section named “Optional” was detected in this file.
The community proposal uses Optional by convention for secondary links that can be skipped for a shorter context. This label does not establish that everything outside it is critical, or that the material inside it is deprecated.
Machine-readable routes
No MCP or Model Context Protocol term was detected in the captured file. 0 links have MCP-related labels or paths. 0 fenced lines match mcpServers, mcp_servers or an mcp add command.
These are text and link observations. No MCP server connection, authentication or tool call was tested.
Index and bundle
Not found at checked URLs
A verified text response establishes a companion at the checked URL. It does not prove the bundle contains all product documentation, that generation is automated, or that it fits an assistant’s context window.
Change evidence
This capture establishes a baseline. Update frequency cannot be determined from one observation.
16 links have release, changelog, deprecation or migration terms in their labels or paths. These provide places to investigate product changes separately.
File changes can reveal documentation edits or navigation changes. They do not by themselves measure product release velocity, accuracy, agent adoption or AI visibility.
753961c3ed026721a41a2ca3b2749a88b8c26a5c34c55b14387b38157c57f5f6Counts use a deterministic parser, not a spec-compliance grade. Unusual Markdown and indented code can fall outside its recognized patterns. See the llms.txt proposal and tokenizer implementation.