Two rendering profiles, one core
Why Rustelo serves HTMX-SSR and Leptos hydration from the same configuration
Two rendering profiles, one core
Rustelo started with one way to render a page: compile every page component to WebAssembly and hydrate it in the browser. For an interactive application that is the right trade. For a site made mostly of articles it is not. The cost lands where the site gets nothing back: a wasm32 build in every pipeline, bundles measured in megabytes, a toolchain that breaks on version mismatches, and hydration mismatches between the server markup and the client signals — a kind of bug that only exists because the page was hydrated at all.
The decision: a typed axis, not a fork
Instead of a second framework, Rustelo added a rendering profile to the one it had
(ADR-006). RenderingProfile is an enum with two values:
LeptosHydration— Leptos server rendering plus WASM hydration. The default, so existing sites keep their behaviour without changing a line.HtmxSsr— HTML rendered on the server, with HTMX for interaction: theme toggle, language switch, filters and forms go through dedicated endpoints with out-of-band swaps. No WebAssembly.
A route can declare its profile; a workspace declares a default; the enum supplies the last fallback. Resolution is route over workspace over default, and it happens during route resolution, so every resolved route already carries its effective profile.
Why typed matters
The profile is a type, not a string scattered across crates. Configuration that names an unknown profile is rejected when it is parsed, and code that dispatches on the profile matches an enum the compiler checks for exhaustiveness. The project keeps that as a hard constraint: the profile names appear as strings only where they are parsed.
What a site gains
A site whose routes are all HtmxSsr skips the wasm32 build entirely — one native target,
a smaller artifact, no wasm-bindgen in CI. Its pages are templates rendered with Minijinja,
and changing a template needs no Rust rebuild.
A site that needs both keeps both. A dashboard-style page that needs instant local feedback can
stay on LeptosHydration while the articles around it are served as plain HTML from the same
binary. The cost is honest: interaction under HTMX-SSR is a round trip to the server, which is
right for content and wrong for a rich interface — which is exactly why the choice is per route.
Extension points instead of switches
Each profile reaches site-specific code through extension points the framework defines and the site fills once at startup: a shell renderer, fragments, filters, templates. Without a registration the framework answers with a typed error instead of a broken swap. The framework stays the same for every site; what changes is what each site registers.
This site is served by the HTMX-SSR profile.
· reads