An experimental SSR framework for Svelte 5 and Bun.
Render everything on the server; ship JavaScript only where it earns its place.
Quick start
Documentation
Setup, hydration modes, routes, hooks, forms, cookies — everything in one place.
Start reading →Demos
Each demo lives on its own page. Pick one below to see the feature in isolation.
Basic
The simplest possible Mochi page — pure server-rendered Svelte. The same component rendered five ways — eager, lazy, visible, rootMargin-tuned, and deferred server island. Drop <ViewTransitions /> into a shared layout to animate full-page navigations with zero JavaScript. Bring your own @keyframes to <ViewTransitions /> via custom={{ in, out }} — here, a funky 3D spin. Two separate islands sharing the same reactive $state. Components marked mochi:defer render server-side on demand after the initial page is delivered. How props travel from a server-rendered parent into a hydrated island — Date, Map, Set, BigInt, URL, typed arrays, and even cyclic refs survive devalue’s round-trip. Islands marked mochi:hydrate:visible hydrate and load their CSS only when scrolled into view. Server islands marked mochi:defer:visible only fetch when the wrapper scrolls into view. Ship fonts via @fontsource packages or standalone .woff2 files — automatically bundled and linked from the page head. A .md file compiled through mdsvex and rendered as a Svelte component, with an embedded <script> block. A five-level recursive tree — hydrating the root carries the whole subtree in one island. Islands inside islands — a mochi:defer server island wrapping mochi:hydrate components, and a server island nesting both a deferred and a deferred-hydrated server island. Nine islands, three unique payloads — each set serialized once and referenced via props-ref. Svelte's native $props.id() inside islands — SSR-consistent, unique per instance, namespaced in server islands.
Crossing the server-client boundary with props