Svelte logo

Svelte by Example: Reactive Built-ins

Svelte provides reactive versions of some JavaScript built-ins. Use their familiar methods, and Svelte updates the interface when their contents change.

In this example, we'll organize todos, change a deadline, and adapt a small message to the screen size.

SvelteMap tracks reads like get and size. Calling set, delete, or clear updates the interface that reads the map.

TodoList.svelte
<script>
  import { SvelteMap } from 'svelte/reactivity';

  const todos = new SvelteMap([[1, 'Walk dog']]);
</script>

<button onclick={() => todos.set(2, 'Read newspaper')}>Add a todo</button>
<button onclick={() => todos.delete(1)}>Remove dog walk</button>
<p>{todos.size} todos</p>
{#each todos as [id, task] (id)}
  <p>{task}</p>
{/each}

Sets

SvelteSet stores unique values. Reads like has and size react to changes made with add, delete, or clear.

TodoList.svelte
<script>
  import { SvelteSet } from 'svelte/reactivity';

  const completed = new SvelteSet();

  function toggle(task) {
    if (completed.has(task)) completed.delete(task);
    else completed.add(task);
  }
</script>

{#each ['Walk dog', 'Read newspaper'] as task}
  <button onclick={() => toggle(task)}>
    {task}: {completed.has(task) ? 'Done' : 'To do'}
  </button>
{/each}
<p>{completed.size} completed</p>

Objects inside a SvelteMap or SvelteSet aren't made deeply reactive. Replace a map value with set, or use a separately created $state object if you need reactive properties.

Dates

SvelteDate updates readers when we change the date with a method like setTime. It doesn't advance automatically like a clock.

TodoDeadline.svelte
<script>
  import { SvelteDate } from 'svelte/reactivity';

  const deadline = new SvelteDate('2026-10-10T12:00:00Z');

  function postpone() {
    deadline.setTime(deadline.getTime() + 24 * 60 * 60 * 1000);
  }
</script>

<p>Walk dog by {deadline.toISOString().slice(0, 10)}</p>
<button onclick={postpone}>Postpone one day</button>

Media Queries

MediaQuery.current reflects whether the query matches. The second argument is the server fallback, because the server can't know the screen size.

TodoList.svelte
<script>
  import { MediaQuery } from 'svelte/reactivity';

  const wide = new MediaQuery('(min-width: 800px)', false);
</script>

<p>{wide.current ? 'Room to plan your todos.' : 'One todo at a time.'}</p>

The message may change when the browser evaluates the query during hydration. Prefer a CSS media query when you only need to change styling.