🍡 mochi

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-shaker

Then 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.