SSR framework for Svelte 5 + Bun with islands-based selective hydration
On this page
Svelte Shaker
svelte-shaker is a whole-program optimizer that slims .svelte source before the Svelte compiler runs — folding props that never vary, removing the dead branches that fold opens up, and narrowing unused CSS. The result is less generated code per component and smaller bundles.
Enable it by passing optimize: true to Mochi.serve():
// src/index.ts
await Mochi.serve({
port: 3000,
optimize: true,
routes: {
'/': Mochi.page('./src/Home.svelte'),
},
});Excluding components
If the shaker mis-transforms a component or you get build-time errors, pass { exclude } with cwd-relative globs to compile those files from their original source. Excluding is always safe — the whole-app scan still covers an excluded file as a call site of the components that import it; only its own output is left unshaken.
await Mochi.serve({
optimize: {
enabled: true,
exclude: ['src/components/ThemeToggle.svelte', 'src/legacy/**'],
},
routes: {
'/': Mochi.page('./src/Home.svelte'),
},
});Disabling temporarily
Pass enabled: false inside the options object to skip shaking while keeping the rest of your config visible:
await Mochi.serve({
optimize: {
enabled: false,
exclude: ['src/components/ThemeToggle.svelte'],
},
routes: {
'/': Mochi.page('./src/Home.svelte'),
},
});This is equivalent to optimize: false but preserves the options so you can re-enable with a single toggle.
Size report
When shaking runs, a per-component before→after source-byte breakdown is logged automatically:
svelte-shaker: slimmed 15 of 86 component(s), 1 excluded
svelte-shaker: source size before → after
src/components/Sidebar.svelte 3.21 kB → 2.74 kB (-14.6%)
…
total (15 changed) 48.9 kB → 41.2 kB (-15.7%)The whole-app scan must cover every component for soundness, so the map includes untouched ones too — slimmed N of M reports how many the shaker actually changed (M) versus the total scanned (the rest are returned verbatim).
Scope
Only components under ./src are scanned. Prop folding is sound only when every call site of a component is in scope, so components imported from outside ./src (e.g. a shared package) are left untouched. If shaking fails for any reason, Mochi logs a warning and falls back to the original, unshaken source.