What are Stores in Svelte?
Tags: javascript, svelte, beginners, tutorial
Published: 2021-12-08 05:29:20

In large applications, passing the state of the application through the component is cumbersome. Often, several Svelte components require the same data (For example, notification or list of cart items). To achieve this feat, Svelte has stores. You can relate it (Svelte stores) similar to Redux in React.

In this article, we learn about:

1. Stores
2. Types of stores
   a. Writable stores
   b. Readable stores
   c. Derived stores

### What you should know before further reading?

- Basic Javascript
- Have a basic knowledge of Svelte
- Know how to [get started](https://ashutosh.dev/how-to-get-started-with-svelte/) with Svelte
- [Adding components](https://ashutosh.dev/how-to-add-components-in-svelte/) in Svelte

### What is Store?

A store is an object that holds data and gains admittance to that data from different parts of the application. Svelte stores are a built-in functionality that facilitates an elegant way to manage the state of the application. They're reactive, which means that they'll update components whenever the data changes across the application. Inshort, stores are global data that hold values or an object. Components subscribe to stores and receive notifications when their values changes.

### Writable Stores

> Every store has a `subscribe` method that returns a function allow us to unsubscribe.  
> ***Writable stores*** allow components to modify their data. It also has `set` and `update` method addition to the subscribe method.

Let's say we have login file that has login key and we want to use it in our app. Create a file `login.js` under the `src` folder.

```javascript
import { writable } from "svelte/store";

export const loginKey = writable('something-secret-is-the-login-key')
```

In the above code, we define a `loginKey` variable and put it under the `writable()`. It is just to define that our `loginKey` variable is `writable` in nature.

And then create a file `WritableStoreComponent.svelte` under the `src` folder and add the following code.

```Javascript
<script>
    import { loginKey } from './login.js'

    let login_key;

    loginKey.subscribe(value => {
        login_key = value
    });
</script>

<div>
    <h2 style="color: darkgreen"> { login_key }  </h2>
</div>
```

In this file, we simply imported the `loginKey` from the `login.js` javascript file. We already discussed, to every store has the `subscribe` function. We use the subscribe function and assign the value to `login_key` variable. And then we render the variable under the `<div>` element.

Last thing, we need to do is in the `App.svelte`

```javascript
<script>

    import WritableComponent from "./WritableComponent.svelte";

</script>

<main>
    <p> Writable Store Example. </p>
    <hr/>

    <div>
        <br />
        <WritableComponent />
    </div>

</main>

<style>
	main {
		text-align: center;
		padding: 1em;
		max-width: 240px;
		margin: 0 auto;
	}


	@media (min-width: 640px) {
		main {
			max-width: none;
		}
	}
</style>
```

If you go the web page, we'll see.

![img](https://ashutosh.dev/content/images/2021/11/Screenshot-2021-11-30-at-12.04.32-AM.png)

------

We see the secret key that we defined in the `login.js` file. But this is not the example of the `writable store`. In general login keys has expiration date and it needs to be updated from time to time basis. How we can do that?

We'll use `set` method to update the `loginKey` variable. Add  the following line `loginKey.set('updated-something-secret-login-key')` to the `WritableStoreComponent` and you'll see the updated key on the webpage.

```javascript
<script>
    import { loginKey } from './login.js'

    let login_key;

    loginKey.subscribe(value => {
        login_key = value
    });

    loginKey.set('updated-something-secret-login-key')

</script>

<div>
    <h2 style="color: darkgreen"> { login_key }  </h2>
</div>
```


![img](https://ashutosh.dev/content/images/2021/11/Screenshot-2021-11-30-at-12.15.32-AM.png)

------

### Readable Store

> As the name implies, it's a read-only store. In Svelte, other components cannot update the readable stores. Unlike writable stores, there's no `set()` or `update()` method. We must initialise the value of the **Readable store** values at the time of creation.

In short, we can say that it is an abstraction around `writable stores` in which `set()` and `update()` method are hidden from the enduser.

Let's create another file `date.js` under the `src` folder.

```javascript
import { readable } from "svelte/store";

export const date = readable(0, (set) => {
    const interval = setInterval( () => {
        set( new Date() );
    }, 1000 );

    return () => clearInterval( interval )
});
```

Here is a simple example, where we can set the date in the store. Please take a look at `readable()` function. It looks complicated at first look but actually it is not.

As it's a readable store, we can't change the value. We just use it in our `App.svelte` file. Add the following code just below the `<WritableComponent>`.

```Javascript
// Under the script
import { date } from "./date";

// Under the main

<hr />

    <p> <strong> Readable Store Example. </strong> </p>
    <hr/>

    <div>
        <br />
        <div>
            { $date.toLocaleString() }
        </div>
    </div>
```

So the complete code is

```javascript
<script>

    import WritableComponent from "./WritableComponent.svelte";

    import { date } from "./date";

</script>

<main>
    <p> Writable Store Example. </p>
    <hr/>

    <div>
        <br />
        <WritableComponent />
    </div>

    <hr />

    <p> <strong> Readable Store Example. </strong> </p>
    <hr/>

    <div>
        <br />
        <div>
            { $date.toLocaleString() }
        </div>
    </div>

</main>

<style>
	main {
		text-align: center;
		padding: 1em;
		max-width: 240px;
		margin: 0 auto;
	}


	@media (min-width: 640px) {
		main {
			max-width: none;
		}
	}
</style>
```

Visit the page and we'll see

![img](https://ashutosh.dev/content/images/2021/11/Screenshot-2021-11-30-at-10.56.04-PM.png)

------

### Derived Stores

> The **Derived store** values depend on other stores. They'll update themselves when the value they are derived from changes. They always listen to other stores and then return to a computed value as a readable store.

We'll modify the code of the `date.js` and import the `derived` function. And then we calculate the total time spends on that page.

```javascript
import { readable, derived } from "svelte/store";

export const date = readable(0, (set) => {
    const interval = setInterval( () => {
        set( new Date() );
    }, 1000 );

    return () => clearInterval( interval )
});

const startDate = new Date()

export const totalTime = derived( date, $time => {
    return Math.round(( $time  - startDate ) / 1000 )
})
```

> You'll find this example in the `Svelte Docs` also but you need to add `return` before Math.round(). Otherwise it will not work.

And then in the `App.svelte`

```javascript
// Under script
import { date, totalTime } from "./date";

// Before </main>
<p> <strong> Derived Store Example. </strong> </p>
    <hr/>

    <div>
        <br />
        <div>
            Total Seconds { $totalTime }
        </div>
    </div>
```


![img](https://ashutosh.dev/content/images/2021/11/Screenshot-2021-11-30-at-11.37.33-PM.png)

Here we can see the Total Seconds added from the `derived stores`. In this article we see, how convenient it is to use the stores in Svelte. They are fairly simple to use and provides great flexibility to share the data between the components. There is one more type of stores and i.e. is `Custom Stores`**,** we'll cover it separately in our next article.