HTMX is hard, so let's get it right

Positioning of HTMX: simplicity vs real complexity

  • Many see HTMX as “back to early web” simplicity: server-rendered HTML, hypermedia, minimal JS, great for backend-focused developers.
  • Several commenters argue the marketing around “simplicity” is misleading once you build anything SPA-like or heavily stateful (e.g., multi-step wizards, complex forms, custom inputs).
  • The blog post is read as a useful corrective: HTMX works, but not “all sunshine and rainbows,” and some problems are simply hard regardless of tool.

State management and where complexity lives

  • A recurring theme: complexity must live somewhere—client or server.
  • HTMX pushes more logic and state to the backend: easier to test, monitor, and type-check (e.g., Go+Templ, Rust+Askama), but requires server sessions, URL encodings, or cookies to track multi-step flows and partial data.
  • Debate over “all app state in the URL”:
    • Pro: bookmarkability, shareable/search URLs, clear, functional-style inputs to pages.
    • Con: modern apps have ephemeral UI state (partial forms, scroll, toggles, nested navigation) that’s awkward in URLs.
  • Alternatives discussed: server-side session objects, cookies keyed by flow IDs, hidden fields, or just keeping state in a single large client-side form and using JS to show/hide steps.

Comparisons with React/Vue/Svelte and hybrid approaches

  • Multiple people report trying HTMX for “simplicity,” then reverting to JSON APIs + React/Vue/Svelte/SvelteKit when complexity appears; they find React tooling (forms, stores, routing) ultimately more straightforward for big apps.
  • Others have shipped real products with HTMX and liked:
    • Smaller JS footprint, fewer dependencies.
    • Staying in one language/codebase, no API duplication.
    • But they admit some features took longer than they would have with a SPA.
  • Common compromise: MPA + HTMX for CRUDish interactions, and embed a SPA-ish island (React/Vue/Solid/web components) for complex widgets.

HTMX-specific patterns and pain points

  • Several commenters note the post’s implementation could be simpler using HTMX features:
    • Out-of-band (OOB) swaps (hx-swap-oob) to update multiple areas (stepper, labels, breadcrumbs).
    • Selective fragment rendering (e.g., template block fragments).
  • Others complain the form-state persistence and per-step round-trips look “gnarly” compared to a single client-side form.
  • There is disagreement over HTTP semantics:
    • Some dislike responding 200 OK for validation errors (done because HTMX discards 4xx bodies by default).
    • Others argue it’s a valid pattern if consistently handled with HTMX events or custom hooks.

Adoption, mental models, and appropriate use-cases

  • Developers with “old-school” server-templating/AJAX background often find HTMX natural; SPA-only developers sometimes struggle with “HTML over the wire” and hypermedia thinking.
  • General convergence:
    • HTMX is excellent for smaller, form-heavy, CRUD, or admin-style apps and incremental interactivity.
    • For large, highly dynamic, stateful UIs, HTMX can feel like fighting the tool, and SPA frameworks or richer JS solutions may be a better fit.