A propos Compétences Expérience Services Blog Contact

HTMX en production : ce que j'ai gardé, ce que j'ai retiré HTMX in production: what I kept, what I removed

Les articles sur HTMX se divisent en deux camps : « la fin des SPA » et « un jouet ». Les retours de production, eux, sont rares. En voici un.

TL;DR : mon cockpit de prospection tourne en production avec HTMX, Go, html/template, Postgres et Redis. Ce qui a tenu : un endpoint par fragment, des templates éclatés par composant, Redis en cache optionnel. Ce que j'ai retiré : le push SSE, qui gelait la page en HTTP/1.1. Et htmx 4.0 vient de sortir, ce qui dit quelque chose sur la maturité de l'approche.

Cet article est pour les devs backend qui veulent une vraie interface sans embarquer un framework front complet.

Le contexte

Le cockpit est mon outil de prospection freelance. Suivi des conversations, veille, analyse de leads. Je l'utilise tous les jours, il tourne en production chez moi.

La stack est courte. Go avec net/http. Des templates html/template. HTMX côté navigateur. Postgres pour les données, Redis en cache.

HTMX est une petite bibliothèque JavaScript. Elle lit des attributs HTML et remplace des morceaux de page par du HTML renvoyé par le serveur. Pas de build front, pas de npm, pas d'état côté client.

Le pari : toute la logique reste en Go, le navigateur ne fait qu'afficher.

La règle qui a émergé : un endpoint, un fragment

Au début, mes templates étaient des monolithes. Le template de base pesait 102 Ko. Deux pages dépassaient 70 Ko chacune.

Ça marche, mais plus personne n'ose y toucher. Le refactor a imposé une règle simple : un endpoint HTMX renvoie un fragment, et chaque fragment vit dans son fichier.

Un dossier fragments/ dédié. Des pages éclatées par composant. Le CSS de base est passé de 1256 lignes à 192, avec un fichier par page inclus automatiquement.

html/template tient très bien la charge, à une condition : le découper comme tu découperais ton code.

Ce que j'ai retiré : le push SSE

J'avais construit du temps réel. Un canal pub/sub dans Redis, un endpoint d'événements, un toast dans la page quand une analyse se terminait. Sur le papier, élégant.

En pratique, la page affichait un chargement sans fin. Un flux SSE est une requête HTTP qui ne se termine jamais. En HTTP/1.1, ce flux permanent occupe un des rares slots de connexion du navigateur vers ton origine.

J'ai déjà raconté cette famille de pièges dans mon article sur les timeouts Go et le SSE. Cette fois, c'était chez moi.

La vraie question n'était pas « comment réparer ». C'était « qui a besoin de ce temps réel ». Réponse honnête : personne. Un rafraîchissement HTMX au clic donne la même information.

Le SSE est parti en un commit. Le temps réel est un coût permanent, pas un cadeau. Paye-le seulement quand le besoin existe.

Ce que j'ai gardé côté serveur

Redis est resté, mais en cache seulement. Les embeddings du matching sont mis en cache avec un TTL. Pareil pour les données de compte les plus relues.

Le point important : tout est optionnel. L'adapter Redis est nil-safe, le cockpit démarre et fonctionne sans Redis, juste plus lentement. Une dépendance optionnelle est une panne en moins.

La file de jobs, elle, est restée dans Postgres. Durable, transactionnelle, déjà là. Le duo Postgres pour l'état, Redis pour l'accélération, couvre tout ce dont une app comme ça a besoin.

htmx 4.0 vient de sortir, et ça compte

Le 28 août 2026, htmx 4.0 est sorti. Le moteur passe de XMLHttpRequest à fetch, l'API moderne du navigateur pour les requêtes. Le projet a sauté la version 3, comme annoncé.

Ce que j'en retiens n'est pas la nouveauté technique. C'est le signal : l'approche hypermedia est entretenue, financée, et pensée pour durer.

Je n'ai pas encore migré. Mon usage est volontairement simple, des attributs de base et des fragments. La migration attendra un créneau calme, et c'est exactement ce que je veux d'une dépendance front.

À qui je recommande ce stack, et à qui non

Fonce si tu es un petit effectif backend, avec un outil interne, un back-office ou une app CRUD. Le gain est énorme : une seule base de code, un seul déploiement, zéro pipeline front.

Réfléchis à deux fois si ton produit vit d'interactions riches côté client. Édition collaborative, offline, animations complexes : là, un framework front se justifie.

Et si tu as déjà une équipe front qui maîtrise son framework, HTMX n'est pas un progrès. C'est un autre compromis.

La checklist si tu tentes HTMX

Les règles que j'appliquerais dès le premier jour, dans l'ordre.

  • Un endpoint HTMX renvoie un fragment, et chaque fragment vit dans son fichier
  • Éclate tes templates par composant avant qu'ils ne pèsent 100 Ko
  • Extrais le CSS par page, chargé automatiquement par convention
  • N'ajoute pas de temps réel sans besoin réel : un refresh au clic suffit souvent
  • Si tu fais du SSE, lis d'abord comment il se comporte en HTTP/1.1
  • Rends tes dépendances optionnelles : l'app doit démarrer sans le cache
  • Garde l'état durable dans Postgres, le cache dans Redis, pas l'inverse

Ce qu'il faut retenir

HTMX en production, c'est surtout de la discipline de templates et des choix serveur assumés. La bibliothèque, elle, se fait oublier.

Mon bilan après des mois d'usage quotidien : je garde le stack, j'ai retiré le superflu, et htmx 4 me conforte.

Tu veux une interface solide sans usine front, ou un avis sur ton stack web Go ? Parlons-en.

HTMX articles come in two camps: "the end of SPAs" and "a toy". Production reports are the rare thing. Here is one.

TL;DR: my prospecting cockpit runs in production on HTMX, Go, html/template, Postgres and Redis. What held up: one endpoint per fragment, templates split by component, Redis as an optional cache. What I removed: the SSE push, which froze the page on HTTP/1.1. And htmx 4.0 just shipped, which says something about the approach's maturity.

This article is for backend developers who want a real interface without adopting a full frontend framework.

The setup

The cockpit is my freelance prospecting tool. Conversation tracking, monitoring, lead analysis. I use it every day, and it runs in production.

The stack is short. Go with net/http. html/template templates. HTMX in the browser. Postgres for data, Redis as a cache.

HTMX is a small JavaScript library. It reads HTML attributes and swaps parts of the page with HTML returned by the server. No frontend build, no npm, no client-side state.

The bet: all the logic stays in Go, the browser only displays.

The rule that emerged: one endpoint, one fragment

At first, my templates were monoliths. The base template weighed 102 KB. Two pages were above 70 KB each.

It works, but nobody dares touch it anymore. The refactor imposed a simple rule: an HTMX endpoint returns one fragment, and every fragment lives in its own file.

A dedicated fragments/ folder. Pages split by component. The base CSS went from 1,256 lines to 192, with a per-page file included automatically.

html/template holds up very well, on one condition: split it the way you would split your code.

What I removed: the SSE push

I had built real-time. A Redis pub/sub channel, an events endpoint, a toast in the page when an analysis finished. Elegant on paper.

In practice, the page showed a never-ending loading state. An SSE stream is an HTTP request that never finishes. On HTTP/1.1, that permanent stream occupies one of the browser's few connection slots to your origin.

I covered this family of traps in my article on Go timeouts and SSE. This time it was my own app.

The real question was not "how do I fix it". It was "who needs this real-time". Honest answer: nobody. An HTMX refresh on click gives the same information.

The SSE left in one commit. Real-time is a permanent cost, not a gift. Pay it only when the need exists.

What I kept on the server side

Redis stayed, but as a cache only. Matching embeddings are cached with a TTL. Same for the most re-read account data.

The important part: everything is optional. The Redis adapter is nil-safe, and the cockpit starts and works without Redis, just slower. An optional dependency is one less outage.

The job queue stayed in Postgres. Durable, transactional, already there. The pair, Postgres for state and Redis for speed, covers everything an app like this needs.

htmx 4.0 just shipped, and it matters

On 28 August 2026, htmx 4.0 was released. The engine moves from XMLHttpRequest to fetch, the browser's modern request API. The project skipped version 3, as promised.

What I take away is not the technical novelty. It is the signal: the hypermedia approach is maintained, funded, and built to last.

I have not migrated yet. My usage is deliberately simple, core attributes and fragments. The migration will wait for a quiet slot, and that is exactly what I want from a frontend dependency.

Who I recommend this stack to, and who not

Go for it if you are a small backend team with an internal tool, a back office or a CRUD-heavy app. The payoff is huge: one codebase, one deployment, zero frontend pipeline.

Think twice if your product lives on rich client-side interactions. Collaborative editing, offline, complex animations: there, a frontend framework earns its keep.

And if you already have a frontend team fluent in its framework, HTMX is not an upgrade. It is a different trade-off.

The checklist if you try HTMX

The rules I would apply from day one, in order.

  • An HTMX endpoint returns one fragment, and every fragment lives in its own file
  • Split your templates by component before they reach 100 KB
  • Extract per-page CSS, loaded automatically by convention
  • Do not add real-time without a real need: a refresh on click is often enough
  • If you do SSE, first read how it behaves on HTTP/1.1
  • Make dependencies optional: the app must start without the cache
  • Keep durable state in Postgres and cache in Redis, not the other way around

What to remember

HTMX in production is mostly template discipline and deliberate server-side choices. The library itself fades into the background.

My verdict after months of daily use: I keep the stack, I removed the excess, and htmx 4 reassures me.

Want a solid interface without a frontend factory, or a second opinion on your Go web stack? Let's talk.