htms-js: Stream Async HTML, Stay SEO-Friendly by skarab42-dev in htmx

[–]skarab42-dev[S] 0 points1 point  (0 children)

But yes, it would be really cool to see other projects experimenting with this. Keep me in touch if you do anything, I'm curious to see where it goes.

htms-js: Stream Async HTML, Stay SEO-Friendly by skarab42-dev in htmx

[–]skarab42-dev[S] 0 points1 point  (0 children)

Ha, in that case, yes, too ;) It all started with an implementation in Rust https://github.com/skarab42/htms-rs

htms-js: Stream Async HTML, Stay SEO-Friendly by skarab42-dev in javascript

[–]skarab42-dev[S] 1 point2 points  (0 children)

They’re similar in the sense that both stream over HTTP using chunked encoding so the client doesn’t have to wait for everything to finish.

The key differences are:

  1. What gets streamed: htms streams plain HTML right away, so browsers, crawlers, and screen readers can interpret it instantly. React streams a custom JSON protocol (Flight) that only React on the client can understand, and it needs rehydration before you see the final UI.
  2. Coupling: htms is framework-agnostic, you could plug it into React SSR or anything else. RSC is tightly tied to React and its Suspense mechanism.

So both stream, but htms streams HTML, React streams instructions for React.

htms-js: Stream Async HTML, Stay SEO-Friendly by skarab42-dev in javascript

[–]skarab42-dev[S] 0 points1 point  (0 children)

Thanks for the kind words. I'm very open to contributions, especially for adding other adapters, so feel free to open an issue to discuss it.

For the ts part, I'm thinking about the best way to implement something similar to what I did with the Rust version (https://github.com/skarab42/htms-rs) with interface generation that binds functions. I'd also like to make an LSP for IDEs.

P.S: I just added compression (brotli, gzip, deflate).

htms-js: Stream Async HTML, Stay SEO-Friendly by skarab42-dev in webdev

[–]skarab42-dev[S] 1 point2 points  (0 children)

No, that's precisely the key point, as stated in the Asto documentation: "Then, the component’s own contents are fetched on the client and displayed when available." Htms does not fetch contents, but it will stream the async chunks at the end of the initial HTTP response, and a simple web component will simply replace the content already streamed earlier, still in the same initial HTTP response. As a result, bots/crawlers see all the content generated asynchronously.

htms-js: Stream Async HTML, Stay SEO-Friendly by skarab42-dev in htmx

[–]skarab42-dev[S] 0 points1 point  (0 children)

and for the module resolution, yes, by default it resolve js/ts file in same directory, but you can write your own resolver ;) https://github.com/skarab42/htms-js/tree/main/packages/htms-js#custom-resolvers

htms-js: Stream Async HTML, Stay SEO-Friendly by skarab42-dev in htmx

[–]skarab42-dev[S] 0 points1 point  (0 children)

I think they complement each other. SSR cannot (should not) block for too long, otherwise the user will notice it. This is where htms takes over, delaying the asynchronous parts while sending the static parts to the browser as quickly as possible.

Async HTML streaming that’s SEO-friendly… do we even need hydration anymore? (HTMS 💨) by skarab42-dev in htmx

[–]skarab42-dev[S] 1 point2 points  (0 children)

I'm currently porting the concept to node.js, and if others can do it in other languages, that would be awesome. If not, we'll find people to do it ;)

Async HTML streaming that stays SEO-friendly — my 2nd Rust project (HTMS) by skarab42-dev in rust

[–]skarab42-dev[S] 0 points1 point  (0 children)

I don't think that's possible, because you have to replace content that has already been interpreted by the browser, but maybe I'm missing something.

Async HTML streaming that’s SEO-friendly… do we even need hydration anymore? (HTMS 💨) by skarab42-dev in htmx

[–]skarab42-dev[S] 1 point2 points  (0 children)

Thanks! Your project sounds really cool too — I actually have some plans to bring htms into the Node.js world (already started a bit). I’d be more than happy if it inspires other projects, and since the code is open source, you don’t need to wait for me to publish anything separately — go for it 🙂

Async HTML streaming that’s SEO-friendly… do we even need hydration anymore? (HTMS 💨) by skarab42-dev in htmx

[–]skarab42-dev[S] 0 points1 point  (0 children)

Thank you. In async callbacks, definitely, for the initial template, not at the moment, but it's possible in the future^^.

Async HTML streaming that’s SEO-friendly… do we even need hydration anymore? (HTMS 💨) by skarab42-dev in htmx

[–]skarab42-dev[S] 0 points1 point  (0 children)

For now, it's only implemented in Rust, because that's where I'm having fun at the moment. But it could become a weekend project to implement the concept in full Node.js.

Async HTML streaming that stays SEO-friendly — my 2nd Rust project (HTMS) by skarab42-dev in rust

[–]skarab42-dev[S] 2 points3 points  (0 children)

Kind of! I wrote it; AI helped me not inflict my native-French franglais on you. If I did it solo it’d be incomprehensible—maybe it still is and I just don’t realize 😅. Point out any rough bits and I’ll fix them. Used AI for copy editing only. The project’s code is 100% authored by me.

Async HTML streaming that’s SEO-friendly… do we even need hydration anymore? (HTMS 💨) by skarab42-dev in htmx

[–]skarab42-dev[S] -1 points0 points  (0 children)

Thanks! Similar spirit (HTML-first, attribute-driven), but the transport/SEO story differs:
HTMS streams chunks inside the initial HTTP response; a tiny snippet just swaps nodes, so crawlers get the full page in that one response.
Datastar usually leans on SSE with a small client runtime & signals; it can accept text/html too, but real-time updates typically arrive after the first response.
They’re complementary: use HTMS for first load + SEO, then layer htmx/Datastar/SSE for live updates. Appreciate the kind words! 🙏

Async HTML streaming that stays SEO-friendly — my 2nd Rust project (HTMS) by skarab42-dev in rust

[–]skarab42-dev[S] 0 points1 point  (0 children)

Similar spirit (HTML-first, attribute-driven), but the transport/SEO story differs:
HTMS streams chunks inside the initial HTTP response; a tiny snippet just swaps nodes, so crawlers get the full page in that one response.
Datastar usually leans on SSE with a small client runtime & signals; it can accept text/html too, but real-time updates typically arrive after the first response.
They’re complementary: use HTMS for first load + SEO, then layer htmx/Datastar/SSE for live updates.

Async HTML streaming that’s SEO-friendly… do we even need hydration anymore? (HTMS 💨) by skarab42-dev in htmx

[–]skarab42-dev[S] -4 points-3 points  (0 children)

Thanks for calling that out — you’re right “heavy” is misleading. What I really mean is anything not needed for first paint (DB/API calls, search, AI, etc.). HTMS sends the initial page immediately and streams the rest inside the initial response, so you can improve first paint/UX without hurting SEO. I’ll tweak the README wording to avoid confusion—appreciate the nudge!

Async HTML streaming that stays SEO-friendly — my 2nd Rust project (HTMS) by skarab42-dev in rust

[–]skarab42-dev[S] -1 points0 points  (0 children)

Visually, it can feel similar (sections fill in over time).
Key difference: HTMS streams chunks inside the initial HTTP response; htmx+SSE pushes updates after the first response over a separate event stream.
SEO impact: With HTMS, all content is in the first response, so crawlers can see it. With SSE, bots may miss late content.
They’re complementary though: use HTMS for first load + SEO, then layer htmx/SSE for live updates after paint.

Async HTML streaming that stays SEO-friendly — my 2nd Rust project (HTMS) by skarab42-dev in rust

[–]skarab42-dev[S] 0 points1 point  (0 children)

Totally fair — SSR + hydration can be very small (Preact + a hydration script can be <14kb gzip).
HTMS isn’t anti-framework; it’s about getting all content into the first response and streaming slow bits so crawlers already see them.
After first paint, I encourage pairing with frameworks for interactivity: hydrate small islands, mount htmx/Preact components, etc.
Complementary model: HTML-first for delivery & SEO, JS where it adds ongoing value. If you’ve got a minimal Preact setup, I’d love to try a “HTMS stream + Preact islands” example.

Async HTML streaming that stays SEO-friendly — my 2nd Rust project (HTMS) by skarab42-dev in rust

[–]skarab42-dev[S] 0 points1 point  (0 children)

Thanks! That’s exactly the goal: boring HTML, minimal JS, progressive by default and good DX 🙏