new·The score now tells you which way it movedA brain's exam only ever grows: its own material writes questions, and so does every question a real caller asked and did not get answered. The score is a percentage over that growing set, so a brain that learned more could post a smaller number — and this week three did. One of them answered two MORE questions than the week before and showed eighteen points less. Printed as a single percentage, that reads as decline to a reader and as punishment to anyone who contributes material.all news →
mozg.beta
Sign in

Svelte · Language · all subjects

core/state

36 notes, read out of this brain and free to use. Each one was extracted from a source and is re-checked against its exam.

Workarounds for exporting $state from modules

To share $state between modules, use one of two approaches: (1) Don't reassign the state variable — instead update its properties, such as exporting a state object and incrementing a property like counter.count += 1; or (2) Don't directly export the state — instead export getter and setter functions that access the state internally.

Cannot directly export and reassign $state from 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. The Svelte compiler transforms references to $state variables, wrapping them in getter and setter calls. Since the compiler operates on one file at a time, if another file imports a $state variable that gets reassigned, the imported reference will be an object (the internal signal), not the value you expect.

Passing $state values to functions passes the current value, not a reference

JavaScript is pass-by-value. When you call a function with a $state value as an argument, the function receives the current value at that moment, not a reference to the reactive variable. If the state changes later, the function does not automatically see the new value. To access current values inside a function, use getter functions or proxy properties with get/set methods.

$state.eager updates UI immediately instead of waiting for sync

When state changes, it may not be reflected in the UI immediately if it is used by an await expression, because updates are synchronized. Use $state.eager(value) to update the UI as soon as the state changes. For example, you might use this to update a navigation bar when the user clicks on a link, so they get visual feedback while waiting for the new page to load. Use this feature sparingly and only to provide feedback in response to user action.

$state.snapshot takes a static snapshot of a deeply reactive proxy

To take a static snapshot of a deeply reactive $state proxy, use $state.snapshot(). This returns a plain object rather than a Proxy object. 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.raw can contain reactive state

Raw state declared with $state.raw can contain reactive state. For example, you can have a raw array containing reactive objects. You can also declare class fields using $state.raw.

$state.raw for non-deeply-reactive state

Use $state.raw when you don't want objects and arrays to be deeply reactive. State declared with $state.raw cannot be mutated; it can only be reassigned. To update it, you must replace the object or array entirely rather than assigning to a property or using array methods like push. This can improve performance with large arrays and objects that you weren't planning to mutate anyway.

Class methods lose 'this' binding in onclick handlers

When calling methods in JavaScript, the value of 'this' matters. If you pass a class method directly to an onclick handler like onclick={todo.reset}, 'this' inside the method will refer to the HTML element rather than the class instance. Use an inline arrow function like onclick={() => todo.reset()} or define the method as an arrow function in the class definition instead.

$state rune creates reactive state

The $state rune allows you to create reactive state, meaning the UI reacts when it changes. Unlike other frameworks, there is no special API for interacting with state — the value is just a regular JavaScript value like a number, and you can update it like any other variable.

$state with arrays and objects creates a deeply reactive proxy

When $state is used with an array or a simple object, the result is a deeply reactive state proxy. Proxies 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, such as a class or an object created with Object.create.

Modifying properties of $state proxies does not mutate the original object

When you update properties of $state 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.

Destructuring a reactive $state value breaks reactivity

If you destructure a reactive value declared with $state, the references are not reactive. They are evaluated at the point of destructuring, just like normal JavaScript. Changes to the original reactive object will not affect the destructured variables.

$state in class fields and constructor

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. The compiler transforms these into get/set methods on the class prototype referencing private fields, meaning the properties are not enumerable.

Svelte provides reactive implementations of built-in classes

Svelte provides reactive implementations of built-in classes like Set, Map, Date, and URL that can be imported from 'svelte/reactivity'.

Store definition and contract

A store is an object that allows reactive access to a value via a simple store contract. The svelte/store module contains minimal store implementations that fulfill this contract.

Store subscription via $ prefix in components

Any time you have a reference to a store, you can access its value inside a component by prefixing it with the $ character. This causes Svelte to declare the prefixed variable, subscribe to the store at component initialization and unsubscribe when appropriate. The store must be declared at the top level of the component, not inside an if block or a function.

Assignment to $-prefixed store variables

Assignments to $-prefixed variables require that the variable be a writable store, and will result in a call to the store's .set method.

Local variables must not use $ prefix

Local variables that do not represent store values must not have a $ prefix.

When to use stores in Svelte 5

Prior to Svelte 5, stores were the go-to solution for creating cross-component reactive states or extracting logic. With runes, these use cases have greatly diminished. Stores are still a good solution when you have complex asynchronous data streams or it is important to have more manual control over updating values or listening to changes. For extracting logic, it is better to use runes in JavaScript or TypeScript files with .svelte.js or .svelte.ts file endings. For creating shared state, create a $state object containing the values you need and manipulate said state.

writable store creation and methods

The writable function creates a store which has values that can be set from outside components. It is created as an object with additional set and update methods. The set method takes one argument which is the value to be set; the store value gets set to the value of the argument if the store value is not already equal to it. The update method takes one argument which is a callback; the callback takes the existing store value as its argument and returns the new value to be set to the store.

writable store initialization callback

If a function is passed as the second argument to writable, it will be called when the number of subscribers goes from zero to one (but not from one to two, etc). That function will be passed a set function which changes the value of the store, and an update function which works like the update method on the store, taking a callback to calculate the store's new value from its old value. It must return a stop function that is called when the subscriber count goes from one to zero.

writable store value persistence

The value of a writable store is lost when it is destroyed, for example when the page is refreshed. However, you can write your own logic to sync the value to for example the localStorage.

readable store creation

The readable function creates a store whose value cannot be set from outside. The first argument is the store's initial value, and the second argument to readable is the same as the second argument to writable.

derived store functionality

The derived function derives a store from one or more other stores. The callback runs initially when the first subscriber subscribes and then whenever the store dependencies change. In the simplest version, derived takes a single store, and the callback returns a derived value. The callback can set a value asynchronously by accepting a second argument, set, and an optional third argument, update, calling either or both of them when appropriate. A third argument to derived can be passed as the initial value of the derived store before set or update is first called. If no initial value is specified, the store's initial value will be undefined. If you return a function from the callback, it will be called when a) the callback runs again, or b) the last subscriber unsubscribes. An array of stores can be passed as the first argument instead of a single store.

readonly store helper

The readonly function is a simple helper that makes a store readonly. You can still subscribe to the changes from the original store using this new readable store, but you cannot call set on the readonly store.

get function for reading store values

The get function allows you to retrieve the value of a store to which you are not subscribed. It works by creating a subscription, reading the value, then unsubscribing. It is not recommended in hot code paths.

Store contract specification

A store must contain a .subscribe method, which must accept as its argument a subscription function. This subscription function must be immediately and synchronously called with the store's current value upon calling .subscribe. All of a store's active subscription functions must later be synchronously called whenever the store's value changes. The .subscribe method must return an unsubscribe function. Calling an unsubscribe function must stop its subscription, and its corresponding subscription function must not be called again by the store. A store may optionally contain a .set method, which must accept as its argument a new value for the store, and which synchronously calls all of the store's active subscription functions. Such a store is called a writable store. For interoperability with RxJS Observables, the .subscribe method is also allowed to return an object with an .unsubscribe method, rather than return the unsubscription function directly. Note that unless .subscribe synchronously calls the subscription (which is not required by the Observable spec), Svelte will see the value of the store as undefined until it does.

Use classes with $state fields instead of stores for shared reactivity

Use classes with $state fields to share reactivity between components, instead of using stores.

$state without initial value includes undefined

If $state is declared without an initial value, the resulting type includes undefined. For example, let count: number = $state() results in type number | undefined, causing a type error. Use as casting if the variable will be defined before first use.

Using as casting with $state in classes

In class constructors where a $state property will be initialized in the constructor, use as casting: count = $state() as number. This is useful when TypeScript cannot infer that the variable will be defined before use.

Typing $state with initial value

Type $state like any other variable: let count: number = $state(0). If an initial value is provided, the type is as specified.

StartStopNotifier interface change in Svelte 4

Custom store implementations using the StartStopNotifier interface from svelte/store now need to pass both an update function and a set function. This only affects people implementing stores from scratch, not people using or creating stores with Svelte's built-in store functions.

derived throws on falsy store values in Svelte 4

The derived function will now throw an error on falsy values instead of treating them as stores passed to it.

Classes are no longer auto-reactive in runes mode

In Svelte 5 runes mode, assigning to class properties does not trigger reactivity unless they are defined as $state fields. Wrapping new Foo() with $state() has no effect—only vanilla objects and arrays are deeply reactive.

state_prototype_fixed error: cannot set prototype

Cannot set the prototype of a $state object.

state_referenced_locally warning

The `state_referenced_locally` warning is thrown when a reactive variable is declared, then reassigned, and referenced in the same scope. This 'breaks the link' to the original state declaration, so subsequent references capture only the initial value. To fix, reference the variable lazily, such as by wrapping it in a function. For example, instead of `setContext('count', count)`, use `setContext('count', () => count)` and access it as `count()` in the child component.

Give your agent this brain