Logo

dev-resources.site

for different kinds of informations.

Sharing Runes in Svelte 5 with the Rune Class

Published at
1/16/2025
Categories
svelte
webdev
javascript
Author
jdgamble555
Categories
3 categories in total
svelte
open
webdev
open
javascript
open
Author
11 person written this
jdgamble555
open
Sharing Runes in Svelte 5 with the Rune Class

I generally don't use classes in any TypeScript I write. I believe functions make things simpler, and you no longer get Tree Shaking with methods in a class.

However, using classes with Runes can actually be faster, because they don't have to compile $state variables with get and set or with value... they just work. This is what Rich Harris recommends in many cases.

Sharable Rune

We need a sharable Rune class, and of course we must use Context.

// rune.svelte.ts
import { getContext, hasContext, setContext } from "svelte";


type RCurrent<TValue> = { current: TValue };

export class Rune<TRune> {

    readonly #key: symbol;

    constructor(name: string) {
        this.#key = Symbol(name);
    }

    exists(): boolean {
        return hasContext(this.#key);
    }

    get(): RCurrent<TRune> {
        return getContext(this.#key);
    }

    init(value: TRune): RCurrent<TRune> {
        const _value = $state({ current: value });
        return setContext(this.#key, _value);
    }

    update(getter: () => TRune): void {
        const context = this.get();
        $effect(() => {
            context.current = getter();
        });
    }
}
Enter fullscreen mode Exit fullscreen mode

And we can export custom runes where we want.

// counter.svelte.ts
import { Rune } from "./rune.svelte";

export const counter = new Rune<number>('counter');
Enter fullscreen mode Exit fullscreen mode

This is how most people share $state variables anyway, however, this is safe for the server (see my previous posts in this thread). We must name it like any other context.

Initialize

We must initialize our $state just like anywhere else, only once, in the parent component.

<script lang="ts">
    import { counter } from '$lib/counter.svelte';

    const count = counter.init(0);
</script>
Enter fullscreen mode Exit fullscreen mode

Read Anywhere

We can use it safely in a child component and read the current method.

<script lang="ts">
    import { counter } from '$lib/counter.svelte';

    const count = counter.get();
</script>

<h1>Hello from Child: {count.current}</h1>

<button type="button" onclick={() => count.current++}>
  Increment From Child
</button>
Enter fullscreen mode Exit fullscreen mode

Reactively Update Anywhere

To update a shared $state, we must pass it through a function that can get called.

<script lang="ts">
    import { counter } from '$lib/counter.svelte';

    let value = $state(8);

    counter.update(() => value);
</script>
Enter fullscreen mode Exit fullscreen mode

This allows the update to be reactive. We can pass any signal or store variable, and it will update just like $derived.

Update Normally

Of course, you can update normally as well.

<script lang="ts">
    import { counter } from '$lib/counter.svelte';

    const count = counter.get();

    count.current = 9;
</script>
Enter fullscreen mode Exit fullscreen mode

I hope you find value,

J

javascript Article's
30 articles in total
JavaScript is a versatile language for web development, enabling interactive and dynamic user experiences across all major browsers.
Favicon
7 Developer Tools That Will Boost Your Workflow in 2025
Favicon
How Developers Enable EV Chargers to Communicate with Mobile Apps
Favicon
Creating a live HTML, CSS and JS displayer
Favicon
Sharing Runes in Svelte 5 with the Rune Class
Favicon
Optimizing Mobile Performance and Media Loading for a Dynamic Website
Favicon
Designing for developers means designing for LLMs too
Favicon
Understanding Statement Coverage in Software Testing
Favicon
Understanding Code Coverage in Software Testing
Favicon
Diff JSON: Simplifying JSON Comparisons
Favicon
API Rate Limiting in Node.js: Strategies and Best Practices
Favicon
Introduction to TypeScript for JavaScript Developers
Favicon
11 real-life PWA examples you can learn from in 2025
Favicon
[React]Props tip: the relationship between function parameter and attribute
Favicon
AI TRISM: Transforming Artificial Intelligence Governance
Favicon
Test Case Generator: Revolutionizing Software Testing
Favicon
[Boost]
Favicon
Cรณmo Iniciar y Crecer como Desarrollador Frontend en 2025
Favicon
Building bun-tastic: A Fast, High-Performance Static Site Server (OSS)
Favicon
My React Journey: Project
Favicon
Is JavaScript Still Relevant?
Favicon
From Challenge to Creation: Building a Blog Post Generator with AWS and React
Favicon
How to Use JavaScript to Reduce HTML Code: A Simple Example
Favicon
Poemio
Favicon
Daily JavaScript Challenge #JS-74: Convert Hexadecimal to Binary
Favicon
NPM vs Yarn vs PNPM: Choosing the Right Package Manager
Favicon
Easy Discount Calculation: Tax, Fees & Discount Percentage Explained
Favicon
LogLayer: A Modern Logging Library for TypeScript / JavaScript
Favicon
7 Mistakes Developers Make When Learning a New Framework (and How to Avoid Them)
Favicon
Decreasing server load by using debouncing/throttle technique in reactjs
Favicon
Debugging Adventure Day 1: What to Do When Your Code Doesnโ€™t Work

Featured ones: