Svelte script context module. 3 reasons to use it instead of store

Have you just heard about the script context module and want to know how and where you can use it, how is it different from a store and when exactly you can benefit from using it?

Today I suggest you join me in finding the answers to these questions by building a few Svelte components to help us understand how and when to use the script context module.

I’ve attached images and code examples in this article to better explain the ideas and concepts, but if you want to see the complete code for the components we will build later you can check my Github repository.

If a quick answer to what exactly svelte context module is what you are looking for then here is my best attempt to describe it in two sentences:

Script context module is used to let you export values from your component module like a regular module except for default export. It lets you write code that will be executed once when the module initializes.

The structure of this article:

  • Script context module vs Store. The key differences.
  • Export values from a component’s module using the script context module.
  • Share metadata between components using the script context module.

Get yourself comfortable and let’s try to investigate this topic.

Export values from a component’s module using the script context module

While developing Svelte apps you might have a need to export something different from the component itself from the component’s module.

It can be a function or some constant that you would like to use in some other parts of your application.

Svelte has us covered for cases like this. You can export values from script context="module" and then import them in various other modules.

Let’s see the example of exporting the values from a component and using it in a different component.

// Post.svelte
// The code includes emojis, but I removed them not to break the code snippets.

<script context="module">
  export const getPostTitle = (title = '') => title.toUpperCase()
</script>

<script>
  export let title = ''
  let titleFormatted = getPostTitle(title)
</script>

<style>
  // a few styles for the component to look a bit nicer
  ...
</style>

<div class="post__container">
    <h2>{titleFormatted}</h2>
    <p>An incredible content</p>
</div>
// App.svelte

<script>
  import Post, { getPostTitle } from './Post.svelte'

  const headlineFormattedAsPostTitlte = getPostTitle(`Today's feed!`)
</script>

<h1>{headlineFormattedAsPostTitlte}</h1>
<Post title="post title" />
Export values using script context module example

As you might have seen I’ve used script context="module" and a regular script. They are not interchangeable and you should always have a regular script if your component has some internal logic or state.

Keep in mind that values within script context="module" are not reactive. Your components can access these variables, but be careful. The changes won’t be reflected in HTML after assigning a new value to the variable.

Here I use the exported helper getPostTitle from Post component module to format both – the actual post title and a headline in the parent component.

I could have used this helper in any module where I would import it.

Svelte’s documentation claims you can’t use default exports in script context="module" as the default export is the component itself that makes pretty much sense to me.

Share metadata between components using the script context module

Have you ever needed to calculate metadata from a few component instances and make it accessible to any of them? Script context module may help you with it.

I refer to the shared state as metadata because I haven’t found a way to share the actual app’s data using the script context module. The values within it are not reactive and after re-assign, you wouldn’t see any changes in HTML.

It makes the script context module not usable for this kind of state that should be properly displayed and updated in HTML.

But it can be useful in a few scenarios.

Let’s consider an example of collecting a total number of Post component instances that were rendered.

Collect component’s metadata using script context module example
// Post.svelte

<script context="module">
  let total = 0

  export const getTotal = () => total
  //... other unrelated for this example logic
</script>

<script>
  export let title = ''

  total += 1
  
  // ... more logic from the previous example
</script>

<article>
  <div class="post__container">
    <h2>
      {titleFormatted}
    </h2>
    <p>An incredible content</p>
  </div>
</article>
// PostsList.svelte

<script>
  import Post, { getTotal } from './Post.svelte'
  const posts = ['a post', 'a newer post']

  window.getTotal = getTotal
</script>

<h1>Today's feed!</h1>

{#each posts as post}
  <Post title={post} />
{/each}

If you want to have a reactive state that is shared across components, the Svelte team recommends using stores for this purpose.

I am sure that there are a few other use cases for the script context module that I am not aware of and probably collecting the metadata is not even the main purpose but for sure can it be useful.

Script context module vs Store. The key differences.

The script context module is used to share a state between components and Svelte stores are used for the same purpose, so what’s the actual difference?

Despite the similarity in the task of state sharing between the components script context module and store are designed to achieve different goals.

From what I’ve seen, stores are useful in the next scenarios:

  • Share the state between various components in your app.
  • Reflect the changes in your app’s state reactively. (Show the changes in HTML immediately after the store value changed)

While the script context module shows itself when:

  • The values need to be exported from the component’s module.
  • A piece of code must be executed when the module initializes (before the first instance of the component is rendered as I like to think about it).
  • A piece of state to be shared between the instances of the same component.

Conclusion

We’ve implemented a few components that use script context module to achieve different tasks and found a few differences between the script context module and stores.

To make a quick recap of when you might want to use the script context module and when to use it instead of a store take a look at the bullets from the previous section. They are just above the conclusion heading.

I hope you have learned something new about Svelte with me today.

What next?

I suggest you take a look at this small tutorial section dedicated to the script context module created by the Svelte team.

It has a great example of sharing the code between components and shows again how to export the values from a module.

Also, you might want to read my previous articles Amazing Svelte reactive statements. With code examples and images. and Svelte hot reloading. With Webpack or Rollup.

If you like what I am doing here, would like to support me and to gift me a sincere smile on my face then please contact me at letconstportal@gmail.com, share your feedback about this article, and request new topics to be highlighted on letconst.