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. It folds props that never vary, removes the dead branches that folding opens up, and narrows unused CSS. The result is less generated code per component and smaller bundles.
It is opt-in and ships as a separate package, so apps that do not use it never install the engine. Add it:
bun add -d @mochi-framework/svelte-shakerThen enable it with optimize: true on 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 hit build-time errors, pass { exclude } with cwd-relative globs to compile those files from their original source. Excluding is 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 equals optimize: false but preserves the options so you can re-enable with one toggle.
Size report
When shaking runs, Mochi logs a per-component before→after source-byte breakdown:
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%)slimmed N of M reports how many components the shaker changed versus the total scanned.
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 (a shared package) are left untouched. If the add-on is not installed, or shaking fails, Mochi logs a warning and falls back to the original source.