Svelte provides reactive versions of various built-ins like [`Map`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map), [`Set`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set) and [`URL`](https://developer.mozilla.org/en-US/docs/Web/API/URL) that can be used just like their native counterparts, as well as a handful of additional utilities for handling reactivity. ```js // @noErrors import { MediaQuery, SvelteDate, SvelteMap, SvelteSet, SvelteURL, SvelteURLSearchParams, createSubscriber } from 'svelte/reactivity'; ``` ## MediaQuery
Available since 5.7.0Creates a media query and provides a `current` property that reflects whether or not it matches. Use it carefully — during server-side rendering, there is no way to know what the correct value should be, potentially causing content to change upon hydration. If you can use the media query in CSS to achieve the same effect, do that. ```svelte
The time is {formatter.format(date)}
```{winner} wins!
{:else}{player} is next
{/if} ```see no evil
{/if} {#if monkeys.has('🙉')}hear no evil
{/if} {#if monkeys.has('🙊')}speak no evil
{/if} ```?{params.toString()}
{#each params as [key, value]}{key}: {value}
{/each} ```Available since 5.7.0Returns a `subscribe` function that bridges external, non-reactive changes to Svelte's reactivity system. It's ideal for integrating with browser APIs, WebSockets, or any event-based source outside of Svelte's control. Call the returned `subscribe()` function inside a getter to make that getter reactive. When the external source changes, you call an `update` function, which in turn causes any effects that depend on the getter to re-run. ### The Generic Pattern This pattern shows how to create a reusable utility that encapsulates the external state and subscription logic. ```js // @errors: 7031 import { createSubscriber } from 'svelte/reactivity'; export function createReactiveExternalState() { let state = someInitialValue; const subscribe = createSubscriber((update) => { // Set up your external listener (DOM event, WebSocket, timer, etc.) const cleanup = setupListener(() => { state = newValue; // Update your state update(); // Call this to trigger Svelte reactivity }); // Return cleanup function return () => cleanup(); }); return { get current() { subscribe(); // This "paints" the getter as reactive return state; } }; } ``` ### Implementation Details Internally, `createSubscriber` creates a hidden reactive `$state` variable that acts as a version number. Calling the `update` function increments this version. When the `subscribe` function is called within an effect, it reads this version number, creating a dependency. This mechanism ensures that getters become reactive to the external changes you signal. This approach is highly efficient: - **Lazy:** The `start` callback is only executed when the getter is first used inside an active effect. - **Automatic Cleanup:** The returned cleanup function is automatically called when the last subscribing effect is destroyed. - **Shared:** If multiple effects depend on the same getter, the `start` callback is still only called once. It's best understood with more examples. ### MediaQuery Here's a practical implementation of a reactive `MediaQuery` utility class. ```js // @errors: 7031 import { createSubscriber } from 'svelte/reactivity'; import { on } from 'svelte/events'; export class MediaQuery { #query; #subscribe; constructor(query) { this.#query = window.matchMedia(`(${query})`); this.#subscribe = createSubscriber((update) => { // when the `change` event occurs, re-run any effects that read `this.current` const off = on(this.#query, 'change', update); // stop listening when all the effects are destroyed return () => off(); }); } get current() { this.#subscribe(); // Return the current state, whether or not we're in an effect return this.#query.matches; } } ``` ### Mouse Position This example creates a utility that reactively tracks mouse coordinates. ```js // @errors: 7031 import { createSubscriber } from 'svelte/reactivity'; import { on } from 'svelte/events'; export function createMousePosition() { let x = 0; let y = 0; const subscribe = createSubscriber((update) => { const handleMouseMove = (event) => { x = event.clientX; y = event.clientY; update(); // Trigger reactivity }; const off = on(window, 'mousemove', handleMouseMove); return () => off(); }); return { get x() { subscribe(); // Makes x reactive return x; }, get y() { subscribe(); // Makes y reactive return y; } }; } ``` ### When to use `createSubscriber` - To synchronize Svelte's reactivity with external event sources like DOM events, `postMessage`, or WebSockets. - To create reactive wrappers around browser APIs (`matchMedia`, `IntersectionObserver`, etc.). - When you have a value that is read from an external source and you need components to update when that value changes. It is a more direct alternative to using `$state` and `$effect` for this specific purpose.