Showcase
Interactive islands
All three demo islands, each with its import shown, and how they stay live in static prose.
This page is a showcase. Three live islands sit inside ordinary prose, each one hydrating on its own when it scrolls into view. Between them, everything you read is static server-rendered HTML that never re-runs. That contrast — live spots in a calm document — is the whole idea, and here it is in action.
How islands stay live
Each demo below rendered to HTML on the server, exactly like this paragraph. The difference is the wake hint on its import: it tells the Vite plugin to split the component into its own chunk and emit the code that wakes it. When the island enters the viewport, its chunk loads and Svelte takes over its slice of the DOM.
- The prose is inert. It painted once and will not run again.
- Each island is independent. One waking or updating never touches another.
- State is local to each instance. Two of the same island do not share anything.
The boundary is a wall. When the Counter below counts up, this sentence does not re-render, does not diff, and costs nothing. That hard separation is what keeps a page fast no matter how many islands it holds.
Counter
A minimal client island: local $state and two buttons. It is the smallest possible proof that a live component can live inside prose. Click either button.
It is placed with a single import and a single tag:
<script>
import Counter from '$lib/playground/demos/Counter.svelte' with { wake: 'visible' };
</script>
<Counter />The component itself is plain Svelte 5 — nothing island-specific inside:
<script lang="ts">
let count = $state(0);
</script>
<button onclick={() => count--}>−</button>
<output>{count}</output>
<button onclick={() => count++}>+</button>Stopwatch
A step up: this island runs an effect. Press start and it ticks on a timer, updating many times a second — and still the surrounding prose stays perfectly still, because the update lives entirely inside the island’s boundary.
Same placement pattern, same wake hint:
<script>
import Stopwatch from '$lib/playground/demos/Stopwatch.svelte' with { wake: 'visible' };
</script>
<Stopwatch />Inside, an $effect owns the interval and cleans itself up when the island unmounts:
<script lang="ts">
let elapsed = $state(0);
let running = $state(false);
$effect(() => {
if (!running) return;
const id = setInterval(() => (elapsed += 10), 10);
return () => clearInterval(id);
});
</script>The returned cleanup function is important: it stops the timer if the component ever leaves the page, so a stopwatch does not keep ticking after it is gone.
Palette
The most connected of the three. Drag the slider and it writes a new value to --og-accent on the document root. Because every accented element reads that token, the entire page recolors live — links, buttons, active states, and focus rings all at once.
Placed the same way as the others:
<script>
import Palette from '$lib/playground/demos/Palette.svelte' with { wake: 'visible' };
</script>
<Palette />And the mechanism is just setting a CSS custom property from island state:
<script lang="ts">
let hue = $state(174);
const accent = $derived(`hsl(${hue} 84% 32%)`);
$effect(() => {
document.documentElement.style.setProperty('--og-accent', accent);
});
</script>
<input type="range" min="0" max="360" bind:value={hue} />Three islands, one page
Here is what is actually running on this page:
| Demo | Wakes on | State | Reaches outside itself |
|---|---|---|---|
| Counter | visible | A single number | No |
| Stopwatch | visible | Elapsed time + a timer | No |
| Palette | visible | A hue value | Yes — writes --og-accent |
Notice that even Palette, which changes the whole page’s color, does so through a single shared token rather than by re-rendering anything. It sets one CSS variable; the browser repaints. No prose re-runs, no other island is disturbed.
The point. You can scatter as many islands through a document as you like. Each one is a small, independent, live region in an otherwise static page — and the page stays fast because everything between the islands is HTML that never wakes.
For the deeper mechanics behind all this, read live components. To see these demos alongside every other design element, visit the kitchen sink.