🍡 mochi
An experimental SSR framework for Svelte 5 and Bun.
Render everything on the server; ship JavaScript only where it earns its place.
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
Hello World
The simplest possible Mochi page — pure server-rendered Svelte.Hydration Modes
The same component rendered four ways — eager, lazy, visible, and deferred server island.Shared State
Two separate islands sharing the same reactive $state.Server Island
Component that renders on-demand after the page is delivered.Lazy Islands
Islands that hydrate and load their CSS only when scrolled into view.Font Loading
Ship fonts with your page — fontsource, standalone .woff2, or inside a hydratable island.Island Props
How props travel from a server-rendered parent into a hydrated island — and what devalue does in between.Nested Components
Five levels deep, each child held in $state — hydrating the root carries the whole subtree.Shared Props
Nine islands, three unique payloads — Mochi auto-shares the JSON.Data & serialization
Server Props
Pass data from a route resolver into a Svelte page as props.Data Loading
Server-side fetch from PokéAPI rendered at request time.Cookies
Unified cookies API usable on the server and in the browser.Cache Events
Custom subscriber pipes MochiCache lifecycle events into an in-memory ring buffer.Devalue Serialization
Date, Map, Set, BigInt, cyclic refs — all survive SSR → hydration.Realtime and APIs
Forms
Forms
A login form rendered twice — plain HTML POST and intercepted with {@attach enhance(...)}.Using form return data
An action returns a value via success({...}); {@attach enhance(...)} updates the UI in place, plain HTML re-renders the page.Form Errors
A thrown server error shown inline via {@attach enhance(...)}, or as the Mochi error page on plain submit.Form Redirects
redirect(303, …) intercepted as a JSON envelope, or followed natively by the browser.File Upload
multipart/form-data submission with server-side validation, shown both enhanced and plain.Reloading associated form data
After a successful submit, refetch the related list — or rely on the post-POST page re-render.Cancelling
cancel() skips the fetch entirely; controller.abort() stops a request mid-flight.