Reactivity in Components
Learning objectives
- You know the term reactivity and know how to use
$state()
to make reactive variables.
Reactivity refers to the ability of a variable to change its value and have that change be reflected in the UI. In Svelte, we can make variables reactive by using the $state()
function. This function is given a value, and it returns a variable that Svelte keeps track of. Whenever the value of the variable changes, Svelte will update the UI to reflect that change.
Creating a reactive variable
Create a new Svelte component called Counter.svelte
and place it in the src/components
folder. Add the following code to the component:
<script>
let count = $state(0);
</script>
<p>Count: {count}</p>
In the code above, we are using Svelte's $state()
function to create a reactive variable called count
. We are initializing the value of count
to 0
. We can use the count
variable in the in a similar way as we used properties (at the end, they are all variables).
Import the Counter
component into +page.svelte
and add it to the template. After importing the component, the code in +page.svelte
should look like this:
<script>
import Counter from "$lib/components/Counter.svelte";
import Hello from "$lib/components/Hello.svelte";
import QuestionAndAnswer from "$lib/components/QuestionAndAnswer.svelte";
let qa = {
question: "Can this work?",
answer: "Yes it can!",
};
</script>
<Hello />
<Counter />
<QuestionAndAnswer {...qa} />
<p>
Visit <a href="https://kit.svelte.dev">kit.svelte.dev</a> to read the documentation
</p>
At this point, in the browser, the page should look as follows.

In the console where we launched the application, when we save Counter.svelte
, we also see a notification similar to the following.
Counter.svelte:2:6 count is declared with $state(...) but is never updated.
Did you mean to create a function that changes its value?
The application is telling us that the value of count
is never updated.
Updating the value of a variable
Let's add a setInterval call to the Counter
component to increment the value of count
every second. The setInterval is a global function that's available in browsers (and in JavaScript) that can be used to call a function repeatedly after a given number of milliseconds. The function takes two parameters, the first is the function to call, and the second is the number of milliseconds to wait before calling the function again.
Modify the code in Counter.svelte
to the following. After declaring the reactive value count
, we add a setInterval
call to increment the value of count once every second.
<script>
let count = $state(0);
setInterval(() => {
count++;
}, 1000);
</script>
<p>Count: {count}</p>
Once you save the file, you notice that the count is incrementing in the browser once every second.

No need for additional trickery
In essence, when working with reactive variables, there's no need to explicitly update the user interface. Whenever the value of a reactive variable changes, Svelte will update the UI to reflect that change.
Creating a reactive object
The reactive variable above is a number, but we can make (pretty much) any type of data reactive. Let's adjust our application so that instead of a number, the variable count
holds a reactive object. We can do this by using the $state()
function to create a reactive object.
Modify the application so that we create a reactive object count. The object has a value
and a note
. At the beginning, the value is set to 0, and the note is set to "single digits".
let count = $state({
value: 0,
note: "single digits",
});
Further, as the value is a property of the object count, modify the setInterval
function and the template to use count.value
instead of count
. After the change, the code in Counter.svelte
should look as follows.
<script>
let count = $state({
value: 0,
note: "single digits",
});
setInterval(() => {
count.value++;
}, 1000);
</script>
<p>Count: {count.value}</p>
The application continues to work in a similar fashion. The only difference is that now we are using an object instead of a number. In the image below, we are at count 179.

Let's further modify the application so that it displays the note as well. In the following, the note is shown in parentheses after the count.
<script>
let count = $state({
value: 0,
note: "single digits",
});
setInterval(() => {
count.value++;
}, 1000);
</script>
<p>Count: {count.value} ({count.note})</p>
When we open the browser, and wait for a while, we see a situation similar to the following. In the below image, the count is at 28, and the note states "single digits".

Let's modify the component a tiny bit to adjust the note based on the count. Let's add the following rule: if the count is larger than 9, the note should be "not single digits".
<script>
let count = $state({
value: 0,
note: "single digits",
});
setInterval(() => {
count.value++;
if (count.value > 9) {
count.note = "not single digits";
}
}, 1000);
</script>
<p>Count: {count.value} ({count.note})</p>
Now, when we open up the browser, we see that the note changes from "single digits" to "not single digits" when the count reaches 10.

Reactivity and state
The $state()
function is used to create a reactive variable that has a state. Svelte keeps track of the state, i.e. the value of the variable, and updates the user interface to correspond to the state. The same principles underly the state management of Svelte applications where the state is shared across multiple components. We will look into this later on in the course.