HTMX : Pourquoi j'ai arrêté React pour un projet perso
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-appavec 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 :