SSR framework for Svelte 5 + Bun with islands-based selective hydration
On this page
Hydratable values (experimental)
hydratablesupport is experimental. Please open an issue if you find problems.
Svelte 5’s hydratable(key, fn) computes a value on the server, serializes it into the page, and reads it back during client hydration. Use it to avoid running the same async work twice when a hydrated component fetches data at the top level.
Without it, the function runs on the server and again during hydration:
<script>
import { getUser } from 'my-database-library';
// Runs on the server AND again on the client during hydration.
const user = await getUser();
</script>
<h1>{user.name}</h1>With it, the client reuses the server result:
<script>
import { hydratable } from 'svelte';
import { getUser } from 'my-database-library';
// SSR: runs getUser and serializes the result into the page.
// Client: reads the serialized value and skips getUser.
const user = await hydratable('app:user', () => getUser());
</script>
<h1>{user.name}</h1>Mochi wires this up. Any hydratable() call inside a Mochi.page(...) route or a mochi:hydrate* island is collected during SSR and picked up by Svelte’s hydrate() automatically. Import hydratable straight from svelte.
Serialization
Mochi serializes values with devalue, so Map, Set, Date, URL, BigInt, and circular references round-trip. Promises work too — Svelte stitches them back together on the client.
Limitations in Mochi today
See it in action
Live demos showing key concepts from this page