HTMX : Pourquoi j'ai arrêté React pour un projet perso

Sommaire

Retour d’expérience sur HTMX après avoir développé une app de gestion de contacts.

Le contexte

Je voulais créer une app de gestion de contacts. Rien de fou : une liste, de la recherche, de la pagination, des formulaires CRUD. Le genre de truc qu’on fait en une journée.

J’ai commencé avec React parce que c’est ce que je connais côté front. Au bout de 2h, j’avais :

  • Un create-react-app avec 200Mo de node_modules
  • Un state Redux pour gérer la liste
  • Un composant ContactList, un ContactForm, un SearchBar
  • Toujours aucune donnée affichée

Je passais plus de temps à câbler le state qu’à coder la fonctionnalité.

Le déclic

Un collègue m’a parlé de HTMX. Sa phrase : “Le serveur renvoie du HTML, le navigateur l’affiche. Point.” J’étais sceptique - ça ressemblait à un retour en arrière.

J’ai quand même essayé. En 30 minutes, j’avais ma liste de contacts qui s’affichait. Pas de build, pas de state, pas de composants. Juste du HTML avec quelques attributs.

Comment ça marche

HTMX ajoute des attributs HTML pour faire des requêtes HTTP. Au lieu d’écrire du JavaScript pour fetch puis manipuler le DOM, on déclare le comportement directement dans le HTML.

Avant (JavaScript classique) :

<button onclick="loadContacts()">Charger</button>
<div id="result"></div>

<script>
async function loadContacts() {
  const response = await fetch('/api/contacts');
  const data = await response.json();
  // ... transformer le JSON en HTML ...
  document.getElementById('result').innerHTML = html;
}
</script>

Avec HTMX :

<button hx-get="/contacts" hx-target="#result">Charger</button>
<div id="result"></div>

Le serveur renvoie directement du HTML. Le navigateur sait déjà l’afficher.

Ce que j’ai gagné

Sur mon projet de contacts, voilà ce que ça a changé :

Avant (React)

  • 2 codebases (front React + API Go)
  • Build Webpack
  • State management
  • ~15 fichiers pour le front

Après (HTMX)

  • 1 seule codebase Go
  • Pas de build côté client
  • Templates HTML classiques
  • ~5 fichiers de templates

Le bundle JavaScript est passé de 300Ko à 14Ko (juste HTMX).

Ce qui m’a surpris

La recherche en temps réel. Je m’attendais à galérer. En fait :

<input type="search"
       hx-get="/contacts"
       hx-target="#results"
       hx-trigger="keyup delay:500ms">

3 attributs. Le delay:500ms évite de spammer le serveur à chaque frappe. Côté serveur, je filtre et je renvoie le HTML. C’est tout.

Pareil pour la pagination. Pas besoin de gérer un state “currentPage” côté client. Le serveur sait quelle page afficher, il renvoie le HTML correspondant.

Les limites

HTMX n’est pas magique. Pour mon app de contacts, c’est parfait. Mais je ne l’utiliserais pas pour :

  • Un éditeur de texte riche (trop d’interactions locales)
  • Une app qui doit marcher offline
  • Des visualisations de données complexes avec beaucoup de drag & drop

Si ton app a besoin de beaucoup de logique côté client, React/Vue restent pertinents.

Le code

Le projet est sur git.sr.ht/~gabrielivanes/htmx_todo. C’est du Go avec Gin, mais HTMX marche avec n’importe quel backend qui renvoie du HTML.

Les articles suivants détaillent les patterns que j’ai utilisés :