HTML over WebSockets gains traction as alternative SPA architecture
A blog post on sending pre-rendered HTML via WebSockets instead of JSON sparks debate over SPA design patterns.
What to know
- HTML over WebSockets is a decades-old pattern gaining renewed attention, allowing servers to send pre-rendered HTML rather than JSON, reducing client-side rendering complexity.
- The article cites Chris McCord's 2019 Phoenix LiveView as the modern origin, though earlier implementations existed in Rails; commenters note similar work predates the article's framing.
- The technical community is divided: some argue WebSockets are necessary for low-latency stateful apps (chat, collaboration), while others contend SSE or HTTP with morphing libraries are simpler and sufficient for most use cases.
- Unresolved tradeoffs include state preservation during DOM updates, binary data support, browser tab limits, and whether the approach truly eliminates API contracts or merely relocates them.
“instead of sending JSON and assembling the HTML in the browser, the server sends the HTML already built and the client just places it where it belongs.”
Andros, Article author · en.andros.dev blog · Aug 10
Chris McCord Creator of Phoenix frameworkAndros Technical writer and author
The record 2 press and posts · last 5 days
- parsed to here · Aug 14, 1:13 AM · 1 item above arrived after
The conversation 28 comments and posts from 1 site · verbatim · 196 claimed on the threads
The Hacker News discussion splits between pragmatists who value simplicity and context-dependent design, and engineers debating whether WebSockets or simpler alternatives (SSE, HTTP morphing, typed frameworks like Inertia.js) are the right default. There is skepticism about novelty—multiple commenters cite earlier jQuery/Rails implementations—alongside genuine technical disagreement over latency, in-order delivery, and state management.
The dispute Whether WebSockets are necessary or whether SSE + HTTP fetch (or htmx + morphing) provides the same latency and simplicity with less overhead; WebSocket advocates cite in-order delivery and stateful sessions, while skeptics note modern HTTP/2 multiplexing and point out the complexity of managing real-time DOM updates (state, scroll position, focus) remains unsolved.
HTML over WebSockets solves real problems for interactive apps; context and use case matter more than cargo-culting JSON SPAs.
-
“A lot of the people who oppose this technique don't understand context: The right solution to your problem often involves understanding the problem you're trying to solve!”
gwbas1c · Hacker News -
“In my case, I work on two Blazor websites… The server-side Blazor approach is for an internal web application that has a lot of quick-and-dirty pages…”
gwbas1c · Hacker News
SSE is simpler and sufficient for most apps; WebSockets add unnecessary overhead and complexity.
-
“For most apps just use SSE and the built-in code for making HTTP requests (Fetch) instead of hacking up your own client side JS to make requests over a WebSocket.”
hackingonempty · Hacker News -
“HTTP doesn't guarantee in-order delivery. Websocket messages do. In-order delivery is important for stateful protocols.”
josephg · Hacker News
Typed, data-driven frameworks (Vue/React + InertiaJS, Django Ninja) are better than minimizing JavaScript; the DOM should be a function of data.
-
“I use Django Ninja, Zod, InertiaJS+Vue and its as easy as using Django's templating engine, but static typing ensures my view doesnt emit unrepresentable data…”
aitchnyu · Hacker News -
“I used all of them in various projects… Then I found Inertia.js and never looked back.”
felixding · Hacker News
This is not new; similar patterns existed years ago (jQuery, Rails Sync). The framing oversells novelty.
-
“I remember doing this with jQuery's $.ajax nearly 15 years ago. This seems comically overcomplicated in comparison.”
lexicality · Hacker News -
“Funny he mentioned Chris McCord as the originator of this technique with Liveview. The reality however predates that with Sync in Rails…”
xutopia · Hacker News
- Does HTML over WebSockets truly eliminate API contracts, or just move them inside the WebSocket protocol layer?
- How does DOM morphing handle complex state (filters, form input, scroll position) during live updates—is the complexity merely hidden?
- Why not use WebTransport, which is bidirectional and lower-latency than WebSockets, as of 2026?
- Aug 13
-
I remember doing this with jQuery's $.ajax nearly 15 years ago. This seems comically overcomplicated in comparison. Why bother with the overhead of a websocket?> You do not need to build an API: the server generates HTML and sends it to the client, with no middleman.You're still building an API, it's just inside the websocket handler rather than…
-
I’m not understanding how websockets fixes the issue of pushing JSON to the client side for it to be rendered into HTML. JSON is just a data object can translate into text to place in the HTML document.Moving this to the backend with a templating engine still requires a formatted object, correct? I like SSR rendering, but I think the diagram with…
-
> For most apps just use SSE and the built-in code for making HTTP requests (Fetch) instead of hacking up your own client side JS to make requests over a WebSocket.HTTP doesn't guarantee in-order delivery. Websocket messages do. In-order delivery is important for stateful protocols. For example, you can start a connection by authenticating, then…
-
It would be nice if it was easy to "place the HTML where it belongs", but in a complex app it's never just-replace: you have to preserve a lot of state, wether it is filters, forms, user selection, scroll position, ... so updating live becomes quite a huge work.I've seen good attempts with libraries like idiomorph, but still quite some plumbing to…
-
Having a hard time following the debate—all I want to know, is there a particular use case which makes websockets seem so attractive? A particular network topology?
-
So basically, this entire conversation and article is summed up by 6 in one hand and a half dozen in the other in regards to this method vs traditional SPA's.
-
> the server sends the HTML already built and the client just places it where it belongsMind blown.A much bigger pet peeve of mine is making a SPA when a bunch of HTML pages would do, and would give you sensible URLs and the ability to open more than one tab in the first place.When you actually need a SPA, I'd only go websockets if I really need…
-
> just use SSEAnd then the user opens your website in a handful of tabs, and everything breaks because having enough open SSE connections blocks ordinary http requests to that origin.You can avoid that by using a shared worker for all your tabs, but then you lose the simplicity advantage.
-
I know the point is to minimize JS here, but have we ever considered sending raw JS over the socket? JavaScript can be a lot more compact than the final DOM that it affects. Dynamic JavaScript is much more interesting than dynamic html. SSR HTML is a boring, solved problem. I need something more exciting in my life these days.
-
Perfect. If you live in a city, this is deployed to the edge, you have a low latency, fast, unmetered connection and run a M series mac or decent PC.
-
Something else that I think is interesting here is the new HTML streaming APIs in Chrome: https://developer.chrome.com/blog/declarative-partial-update...These mean that you can for example have a websocket serve just the new HTML, and then let native browser code figure out inserting it into the DOM, without any dependency. I’m guessing things…
- Aug 12
-
"Was Top 7 on Hacker News"Contrast with something like "had 7th most comments on Hacker News"Consider (a) algorithmic ranking, (b) votes and (c) discussion, i.e., comments, aka repliesPerhaps in some cases (b) might drive (a) which then drives (c), and of course (a) can drive (b)As such, (b) votes and (a) ranking are almost always alignedHowever…
-
I used all of them in various projects: "traditional" Ajax-based SPAs, HTML over WebSockets/SSE, etc. Then I found Inertia.js and never looked back.With Inertia.js, you get the real feel of an SPA without the complexity of maintaining APIs just for the frontend. You can even make some pages plain HTML (like the homepage, legal pages, etc.), while…
-
We were also doing this at Booking.com many years earlier, using morphdom and custom templating libraries. I think I wrote the first version in 2014-2015.
-
A lot of the people who oppose this technique don't understand context: The right solution to your problem often involves understanding the problem you're trying to solve!In my case, I work on two Blazor websites: One is standard in-browser WASM with Restful JSON (and some CSV) over http; the other is server-side Blazor that uses the websocket…
-
>Safer against injection: since the server renders and escapes the HTML before sending it over the channel, an attempt to sneak in a <script> travels as inert text and reaches your neighbor's screen as plain letters, not as code. The same architecture that makes a chat trivial makes it immune to XSS.I strongly disagree with this point, and in…
-
Reading this is especially interesting to me because it's what I've been working towards for the last 14 years or so. Though like this group, it also came together for me piece by piece.I got interested in this specific idea back in the early days of Firebase I saw someone built a realtime HTML component with PolymerJS called 'collection' and I…
-
Funny he mentioned Chris McCord as the originator of this technique with Liveview. The reality however predates that with Sync in Rails that you guessed it... was also Chris McCord's doing. Rails at the time didn't have the capacity to handle it so it was just a tech demo then and a big reason why Chris McCord moved to Phoenix. He was once a…
-
No mention of WebTransport makes me very doubtful of this article. It's 2026, all browsers support it and it's bidirectional and lower-latency than WebSocket.
-
> Place the HTML where it belongsWell, some drawbacks are not accounted for when replacing HTML parts: input elements lose focus, if some view was scrolled, then it gets unscrolled, jumping under user's pointer etc.
-
I like the Vue/React/Svelte model of the DOM being a function of the data. For example, in a shopping cart, I add two chocolates, the number against the chocolate, the count at top and a banner encouraging me to reach X total all center around a data structure.I use Django Ninja, Zod, InertiaJS+Vue and its as easy as using Django's templating…
-
Close but htmx with SSE and dom swaps and morphing gets you there without reinventing any wheels.Pretty much every web app I build has this pattern in it from day 1, as they all quickly expand to have a realtime inbox and notifications subsystem to support workflows and agents.
-
> The latency is the same because modern browsers multiplex HTTP requests over a single TCP connection that is left open.In my experience this isn’t true; firstly you’re relying on an implementation detail of the platform that you’re executing on, of which you have no control over on the client side. Secondly, even if you aren’t opening a new…
-
> The quick rule: if you need bidirectional, low-latency communication (chat, collaboration, games), WebSocket; if you only push from the server, SSE is simpler and cheaper to operate.For most apps just use SSE and the built-in code for making HTTP requests (Fetch) instead of hacking up your own client side JS to make requests over a WebSocket…