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