HTML over WebSockets: real-time SPAs with barely any JavaScript

redbell 175 points 119 comments August 12, 2026
en.andros.dev · View on Hacker News

Discussion Highlights (18 comments)

ChiperSoft

Is this satire? Rage bait? Why would you ever do this? Just make a normal website!! You've invented an MPA with extra steps!

hackingonempty

> 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. The latency is the same because modern browsers multiplex HTTP requests over a single TCP connection that is left open. Maybe if you are making many client requests per second there is an advantage to not sending full headers/cookies/etc... on each request but not if you're sending requests in response to user clicks/touches. Any sufficiently complicated SPA contains an ad hoc, informally-specified, bug-ridden, slow implementation of half of Fetch.

doublerabbit

> Simple, elegant and fast. Until someone bombs your websocket server and you then have nothing at all.

hyperhello

What’s wrong with this idea, really? It’s redundant because you can serve HTML to requests with Apache or Ngnix or any other server on the happy path. What’s right with the idea, really? It’s exactly what the tried and true preferences of developers have been shown to be: getting in the way of the happy path for no reason. Now you can have build steps and put story points in Jira and do it all on the server where we don’t have to see it, and the success condition is that the text gets served. Both sides can be happy now.

nchmy

A good response to this post https://yagni.club/3mstlyuxe5s26

pjmlp

Love how DHTML, ASP.NET Ajax, JSF Ajax kind of keeps being re-invented.

frollogaston

So a RESTless webserver

nzoschke

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.

greymoonx

What happened to the live chat xD

mattrighetti

> Less traffic and less latency per action: a single persistent connection avoids repeating the TCP handshake and the HTTP headers on every interaction. You don’t need a TCP connection for everything. If you’re optimizing for that you can consider client-side caching which you can instruct using cache headers that every browser support. That usually reduces heavy hitters by a lot, even if you set the browser TTL to 1 minute which is fine for most of the scenarios.

conradfr

Just wanted to mention that in PHP besides Laravel Livewire there's also Symfony Live Components[0] [0] https://symfony.com/bundles/ux-live-component/current/index....

floodfx

A few years back I wrote a backend implementation of the LiveView protocol in Typescript ( https://liveviewjs.com ) and played around with another BunJS-specific implementation ( https://hotdogjs.com/ ). (Also did Java and Go versions but that's another story.) There isn't an official "protocol" so I had to figure it out by watching the WS traffic and determining how it worked which was fun if not tedious. That said, the more I learned, the more I was impressed by the efficiency and the programming model which felt simpler yet more powerful than SPAs. I did get to a point where I just got too busy to keep up and over the last couple of years things have changed a bit on the "protocol" side. But recently (a week ago-ish), I started poking at the old LiveViewJS repo with the help of coding agents. Now that Phoenix is past 1.0 and the JS runtimes (Node, Deno, Bun) have more overlap in terms of APIs and library support, I think it will be more straight forward and frankly easier to get and stay at parity.

aitchnyu

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 engine, but static typing ensures my view doesnt emit unrepresentable data, my TS doesnt accept unrepresentable data, Vue+TS dont allow logic errors in template. AI makes it effortless. Again, the loaded page is a function of the data supplied at the view. With HTMX, I'm writing several server-side functions to mutate the DOM imperatively and using HTML attributes to call them. Its great for forms but that shopping cart example needs code scattered across multiple functions and templates.

egeozcan

This gives me too much <script runat="server"> or even JSF vibes.

deepsun

> Place the HTML where it belongs Well, 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.

austin-cheney

HTTP over WebSockets : Sounds like the same tag line I have been using in my project for the past 2 years. https://github.com/prettydiff/aphorio My approach is pretty simple. Since the connection phase of WebSockets is RFC2616 compatible, per RFC6455, you can use the same server logic to connect both.

carllerche

Topcoat (Rust) is aiming taking this approach as well: https://github.com/tokio-rs/topcoat . The project is still in the early days. It won't require WebSockets, but WebSockets will be an option.

goatlover

Is Meteor.js still in use? I recall early on it was all the rage, but that didn't last too long. I had thought it delivered updated html over sockets, but maybe it was just the data. Did seem to be a bit more of a heavy JS framework, but it's been years.

Semantic search powered by Rivestack pgvector
4,128 stories · 37,281 chunks indexed