Fuddle: a 2025+ evolution of the Elm idea

SSR like Node. Templating like PHP.With fewer footguns.

Fuddle is designed for teams who want the speed of server-side rendering and templates, but with functional structure, predictable behavior, and safer boundaries. Think: modern Elm-style UI modeling, extended for SSR-first webapps and high-throughput templating.

SSR-native UIfloating executioncompiled templatescontrolled JS interopmulti-locale UIJS / Wasm targets
Pick a focus
tap to switch
SSR: render on the server, hydrate only what needs it
Fuddle is designed so your UI is a pure function of state, and SSR becomes the default path — not a special-case build mode.
Why not “just Node SSR”?
Fuddle aims to keep SSR speed but reduce runtime ambiguity via a functional UI model + predictable server integration.
Why not “just PHP templates”?
Fuddle templating is designed to compile and validate structure up front, instead of treating HTML as a string concatenation hobby.
Fuddle build pipeline (3D)
Tap nodes
SSR • JS • Wasm • Templates
A single UI model can target multiple runtimes while preserving behavior.
Execution surface map
hover nodes
Hover a node
See how Fuddle connects SSR, client interactivity, templating, and server continuations.

SSR without the “two apps” problem

SSR often becomes a second implementation: different render path, different data loading model, different failure modes. Fuddle’s goal is to make SSR the default path by treating UI as a pure function of state.

SSR design goals
  • Deterministic render: same input state → same DOM output.
  • Thin client: hydrate only interactive islands, not the whole app.
  • Event routing: HTMX-over-websocket style events with explicit payloads.
  • Server continuations: call complex server logic without leaving the UI model.
SSR trade-off slider
Move the slider to see how “more SSR” changes the client footprint (toy model).
Client JS
~120KB
p95 TTI
~1.5s
Server work
~moderate
Replace with your real bundle size and p95 measurements.
SSR request loop
tap steps
Tap a step
The goal: make SSR the happy path, and client interactivity a controlled extension.
What replaces “Express middleware”?
Typed request boundaries + explicit parameter marshaling + validated event payloads.
What replaces “React hydration everywhere”?
Hydrate only interactive regions and route events explicitly back to the server.

Templating that compiles (and stays readable)

PHP made templating popular because it’s fast to write. The cost is that templates drift into logic soup and runtime failures. Fuddle aims to keep the speed while moving errors to compile-time and making templates navigable.

AST-aware parsing
less guessing
Parse at the syntax tree level (not regex scanning) to make transformations safer and faster.
Compiled templates
fast render
Emit compact renderers optimized for runtime instead of interpreting template text per request.
Safe value binding
less injection
Prefer explicit data binding rules over string concatenation patterns that hide injection paths.
Template duel
switch modes
Rendered output (toy)
This is a conceptual demo: it illustrates shape, not an actual compiler in your browser.

Interop without losing control

Real apps need JavaScript. The goal is not “no JS” — it’s bounded JS. Fuddle aims to make interop explicit: you can embed JS where it’s needed, but keep the rest of the UI predictable.

Interop principles
  • Explicit boundaries: ports/bridges define what crosses the line.
  • Typed payloads: JS events become structured messages.
  • SSR-first: JS is optional for initial render.
  • Islands model: isolate imperative behaviors to small regions.
DX: the “15 minutes and it runs” target
# a minimal mental model
Wapp/
 app/			# Fuddle UI modules + routes
 server/		# Haskell handlers + continuations
 db/			# explicit SQL statements
 templates/		# compiled templates (Cannelle)
 assets/		# Tailwind, icons, media

# the loop
  # 1) edit Fuddle UI
  # 2) hot reload
  # 3) server continuations handle complex actions
  # 4) explicit SQL for data work
  # 5) SSR is default, interactivity is opt-in
Want a migration path?
Start with a single SSR page. Add islands for interactivity. Replace hot paths first.
Prototype form: stores locally. Wire to your backend.