Si reduces el desarrollo front-end a su esencia, obtienes dos preguntas:

  1. ¿Cómo cruza la red la intención del usuario?
  2. ¿Cómo cambia el DOM en respuesta?

Durante una década respondimos ambas con frameworks JavaScript. HTMX las responde con HTML. No es nostalgia—es arquitectura. Al enviar fragmentos HTML sobre HTTP y dejar que los atributos en los elementos describan el comportamiento de red, mueves la lógica de vuelta a donde la web está optimizada: servidores que renderizan documentos y documentos parciales. HTMX luego añade justo la suficiente potencia del cliente (AJAX, SSE, WebSockets, transiciones CSS) a través de atributos hx-* para hacer que las interfaces modernas se sientan instantáneas sin construir un sistema operativo del cliente en tu bundle. La documentación oficial lo dice así: HTMX "te permite acceder a características modernas del navegador directamente en HTML", y es intencionalmente pequeño (≈16.6 KB comprimido en la línea 2.x).

En 2024–2025 HTMX maduró de "hack ingenioso" a opción seria. La versión 2.0 eliminó el soporte para IE, movió los transportes en tiempo real a extensiones de primera clase, y ajustó los valores por defecto; el equipo luego reconsideró abiertamente el snapshotting de historia, abogando por semánticas más simples de request-on-back para evitar el caching local frágil. Estos no son ajustes cosméticos; son movimientos de arquitectura.

Esta guía es para el momento en que miras tu próximo proyecto y preguntas: ¿Debería recurrir a React/Next/Nuxt/SvelteKit—o puedo hacer más con menos usando HTMX?

Definiremos tamaños de proyecto, tomaremos la decisión, y mostraremos patrones, trampas y un ejemplo de producción con SSE y WebSockets.

---

Marco de decisión rápida

Usa HTMX cuando:
  • Tu "interactividad" es principalmente solicitud/respuesta (enlaces, formularios, actualizaciones parciales)
  • Quieres la verdad renderizada en el servidor con una ruta de validación, un caché
  • Necesitas tiempo real pero no un OS de cliente (SSE/WebSockets vía atributos)
  • Quieres UI direccionable por URL sin un router de cliente
Mantente con frameworks cuando:
  • Offline-first es obligatorio (almacén del cliente, sincronización, resolución de conflictos)
  • Tienes una aplicación de cliente verdaderamente con estado, multi-panel (editores nivel Figma, Notion)
  • Estás construyendo una plataforma de componentes para compartir entre muchos equipos
La realidad: Muchos productos mezclan: HTMX para la mayoría de las páginas; una sola "isla" de framework para un editor embebido o área intensiva en visualización.

---

Qué hace realmente HTMX (y qué no hace)

La idea central: usa atributos HTML para emitir solicitudes HTTP e intercambiar el HTML devuelto en la página actual.

Atributos que usarás todos los días

  • hx-get, hx-post, hx-put, hx-delete: envía solicitudes e intercambia la respuesta
  • hx-swap: controla cómo se inserta el contenido (innerHTML, outerHTML, beforeend, afterbegin, etc.)
  • hx-trigger: decide cuándo se disparan las solicitudes (click, change, every 5s, o eventos personalizados)
  • hx-target: elige qué parte de la página actualizar
  • hx-boost: convierte enlaces y formularios en navegación AJAX con fallback graceful
  • hx-push-url: actualiza la URL/historia al intercambiar contenido

Tiempo real vía extensiones

  • SSE vía hx-ext="sse", sse-connect="/events", y sse-swap="message" para actualizaciones unidireccionales servidor→cliente sobre HTTP
  • WebSockets vía hx-ext="ws", ws-connect="/socket", y ws-send en formularios para actualizaciones bidireccionales

Intercambios Out-of-Band

hx-swap-oob permite al servidor actualizar otras partes del DOM incluidas en la misma respuesta (ej., actualizar un contador mientras devuelves un diálogo).

Conciencia del servidor

HTMX envía headers como HX-Request: true, HX-Boosted, HX-Target, y soporta headers de respuesta como HX-Redirect, HX-Location, y HX-Push-Url para que tu servidor pueda devolver fragmentos vs páginas completas y aún controlar la navegación.

Lo que HTMX no hace

Gestión de estado del lado del cliente à la Redux, un DOM virtual, primitivas de composición de componentes, o un router de cliente. Para "código pegamento" en el cliente, usa compañeros mínimos como hyperscript o Alpine.js—ambos funcionan bien con HTMX cuando necesitas estado local o lógica DOM en el navegador.

---

Verificación de realidad 2025: HTMX 2.x y el "fetchening"

A mediados de 2025, HTMX 2.x es la versión actual (2.0.6 notada públicamente). 2.x terminó el soporte de IE, eliminó los viejos hx-sse/hx-ws inline a favor de las extensiones anteriores, e hizo el comportamiento de historia más explícito (y, cada vez más, más simple). Si te quemaste con cachés de snapshot en flujos de atrás/adelante en 1.x/principios de 2.x, los mantenedores ahora te señalan hacia deshabilitar snapshots o dejar que la navegación vuelva a obtener contenido—predecible, más seguro, y más fácil con los servidores de hoy.

Traducción: En 2025 puedes tratar al navegador más como un terminal delgado y confiable de nuevo, y al servidor como tu máquina de estados.

---

Decidiendo: Pequeño, Mediano, Grande (sé honesto sobre el alcance)

La mayoría de los equipos sobreestiman el tamaño del proyecto. Usa esto:

Pequeño (1–8 pantallas, acoplamiento bajo)

Tablas CRUD, búsqueda y filtros, formularios, autenticación, un dashboard, un par de modales. Sin requisitos offline. Estado de cliente mínimo entre pantallas.

Por defecto: HTMX + tu templating del servidor. Añade Alpine/hyperscript para estado de UI local. Sin paso de build de framework. Equipo: 1–3 ingenieros, horizonte de entrega de 2–8 semanas.

Mediano (8–30 pantallas, acoplamiento moderado)

Suites de admin, back-offices de CMS, sitios de suscripción, dashboards multi-usuario, algo de tiempo real. Offline limitado. Algunos componentes ricos (calendario, gráficos).

Sesgo: HTMX primero. Usa hx-boost para navegación, hx-push-url para historia, SSE para actualizaciones en vivo, y añade una micro-lib reactiva (Alpine/hyperscript) donde el estado local sea pesado. Mantén las URLs direccionables y el servidor como fuente de verdad. Añade una pizca de SPA en una sola página solo si es necesario. Equipo: 3–12 ingenieros, entrega de 2–6 meses en iteraciones.

Grande (30+ pantallas, acoplamiento pesado)

Suites de producto complejas, interacciones de cliente densas, offline, editores embebidos, apps multi-panel con drag-drop y grandes modelos en memoria.

Sesgo: Usa un framework (React/Next, Nuxt/Vue, SvelteKit) para la zona caliente que genuinamente necesita una aplicación de cliente. Usa HTMX en otros lugares—marketing, docs, páginas de cuenta, configuración, UI de facturación. Tu plataforma se vuelve híbrida. El movimiento equivocado no es elegir HTMX; es usar una herramienta a través de formas de problema muy diferentes.

---

Cuándo HTMX reemplaza un framework (y cuándo no debería)

Sí reemplaza un framework cuando...

  • Tu "interactividad" es principalmente solicitud/respuesta. Enlaces, formularios y actualizaciones parciales dominan. Los atributos HTMX cubren el 90% de lo que escribirías código de cliente.
  • Quieres la verdad renderizada en el servidor. Prefieres una validación, una ruta de renderizado, un caché. El HX-Request de HTMX permite a tu servidor devolver HTML parcial para fragmentos y páginas completas de lo contrario.
  • Necesitas tiempo real pero no un OS de cliente. SSE y WebSockets son directos y conducidos por atributos.
  • Quieres UI direccionable por URL sin un router de cliente. hx-boost y hx-push-url mantienen la historia honesta.

No reemplaza un framework cuando...

  • Offline-first es obligatorio. Necesitarás un almacén de cliente, sincronización, resolución de conflictos, orquestación de service worker—fuera del mandato de HTMX.
  • Tienes una aplicación de cliente verdaderamente con estado, multi-panel (piensa en editores nivel Figma, Notion). La hidratación y orquestación de estado del cliente son tus problemas principales. Considera React Server Components/Next, Nuxt, o SvelteKit.
  • Estás construyendo una plataforma de componentes para compartir entre muchos equipos. Los ecosistemas de framework siguen siendo los más fuertes para esa clase de problema.

El híbrido saludable

HTML-over-the-wire no es único de HTMX—Hotwire/Turbo lo hace en Rails, Symfony, Django y otros. El patrón es estable y mainstream. Muchos productos mezclan: HTMX para la mayoría de las páginas; una sola "isla" de framework para un editor embebido o área intensiva en visualización.

---

Patrones de arquitectura que realmente entregan

1) Navegación progresiva con hx-boost

Envuelve tu contenido principal en hx-boost="true" y deja que los enlaces/formularios se conviertan en solicitudes AJAX que intercambian en

. La página aún funciona con JS desactivado.

<main id="app" hx-boost="true" hx-target="#app">
  <a href="/invoices">Facturas</a>
  <form action="/search" method="get">
    <input name="q">
  </form>
</main>

Los enlaces boosteados emiten un GET, empujan una entrada de historia, apuntan al body (o tu hx-target elegido), y hacen fallback gracefully.

2) Haz el estado direccionable por URL con hx-push-url

<div id="results"
     hx-get="/reports?period=Q2"
     hx-push-url="true"
     hx-target="#results"
     hx-trigger="change from:#period-select">
</div>
hx-push-url actualiza la barra de direcciones e instruye a HTMX a manejar la historia. Los usuarios pueden marcar y compartir estados filtrados.

3) Tiempo real sin una SPA: SSE y WebSockets

SSE para flujos servidor→cliente (tickers de acciones, progreso, notificaciones):
<div id="feed" hx-ext="sse" sse-connect="/events" sse-swap="message"></div>

SSE corre sobre HTTP, atraviesa proxies limpiamente, y es unidireccional. La extensión maneja la reconexión y eventos nombrados.

WebSockets cuando el navegador también necesita hablar de vuelta:
<div hx-ext="ws" ws-connect="/ws/room">
  <div id="chat"></div>
  <form ws-send>
    <input name="message">
  </form>
</div>

Los mensajes entrantes pueden incluir snippets hx-swap-oob para actualizar objetivos en cualquier lugar de la página; la extensión encola mensajes salientes y reconecta con jitter.

4) Actualizaciones Out-of-Band para "mientras estás aquí..."

Devuelve el fragmento principal y una actualización de insignia en una respuesta:

<div id="modal">...</div>
<div id="alerts" hx-swap-oob="true">¡Guardado!</div>

La respuesta del servidor actualiza tanto el modal como la región de alertas.

5) Comportamiento del cliente: usa hyperscript/Alpine con moderación

  • hyperscript favorece comportamientos pequeños y legibles inline: _="on click toggle .open on #menu"
  • Alpine.js trae estado pequeño y reactivo cuando lo necesitas (dropdowns, tabs), y hay una extensión alpine-morph para preservar el estado de Alpine a través de swaps

---

Rendimiento, payload y velocidad percibida

  • Tamaño del bundle: HTMX 2.x es ≈16–17 KB comprimido (más cualquier extensión que uses). Para muchas apps eso reemplaza 100–300 KB de framework + router + gestión de estado + código de hidratación.
  • Arranques en frío: Sin boot/hidratación de framework, el tiempo interactivo es a menudo "HTML parseado" + "un pequeño eval de script".
  • Red: Estás enviando fragmentos HTML, no JSON + templates de cliente. Eso ahorra duplicación (no "renderizar en servidor luego renderizar de nuevo en cliente") y permite a los CDNs cachear fragmentos agresivamente.

---

Historia, caché y la guía de 2025

HTMX históricamente hacía snapshot del DOM para navegar hacia atrás instantáneamente. En la práctica, scripts de terceros y peculiaridades del navegador hacen los snapshots frágiles. Los mantenedores ahora recomiendan deshabilitar el snapshotting por URL con hx-history="false" (o globalmente) y dejar que el navegador vuelva a obtener contenido en atrás/adelante. Aún obtienes historia correcta, pero menos heisenbugs y menor superficie de ataque de estado del cliente.

---

Seguridad: XSS, CSRF y corrección de fragmentos

  • XSS: Estás renderizando HTML desde el servidor; escapa datos no confiables en el límite del template y mantén el auto-escape de tu motor de templating activado. La guía de XSS de OWASP aplica 1:1 aquí.
  • CSRF: Incluye tokens CSRF en POST/PUT/PATCH/DELETE. Con Django, por ejemplo, usa csrf_token en formularios o añade el token vía hx-headers.
  • Descargas de archivos: Porque HTMX usa XHR/fetch, generalmente rediriges el navegador (HX-Redirect) a un endpoint no-AJAX para descargas reales.

---

Comparación con frameworks modernos (edición 2025)

  • React / Next.js: Server Components eliminan código de data-fetch del cliente y reducen hidratación, pero aún mantienes un grafo de componentes, límites y bundling; adoptas convenciones para streaming y capas de caché; y eliges componente de cliente vs servidor cuidadosamente. Esto es poderoso, pero pesado si tu UI es principalmente hypermedia clásica.
  • Nuxt (Vue) y SvelteKit: Ofrecen historias SSR/ISR/híbridas igualmente excelentes y son geniales cuando necesitas estado de cliente rico y grandes bibliotecas de componentes.
  • Hotwire/Turbo: El primo más cercano—un conjunto de herramientas nativas de Rails (Drive/Frames/Streams) para HTML-over-the-wire con buenas primitivas de tiempo real y una "sensación de SPA sin el bloat de SPA". HTMX te da la misma idea en un estilo agnóstico de framework, primero atributos.
Usa las armas pesadas donde debes. Usa HTML-primero en todos los demás lugares.

---

Un ejemplo del mundo real: Pedidos en vivo (SSE + WebSockets), cero framework

Escenario

Estás construyendo una consola de "Pedidos en vivo" pequeña–mediana para una cadena de cafeterías. Requisitos:

  • Lista de pedidos paginada con filtros y estado compartible por URL
  • Inyección de fila "nuevo pedido" en tiempo real
  • Botón para aceptar un pedido y ver el contador de insignias bajar
  • Cambios de estado transmitidos (el display de cocina actualiza a todos)
Servidor: Cualquier plataforma—Node, Python, Go—renderizando templates para fragmentos y páginas completas. Cliente: HTMX 2.x + SSE + WebSockets. Sin framework.

1) Layout y navegación boosteada

<body>
  <header>
    <a href="/orders" hx-boost="true">Pedidos</a>
    <a href="/reports" hx-boost="true">Reportes</a>
    <span id="badge" class="badge">0</span>
  </header>

<main id="app" hx-boost="true" hx-target="#app"> {{ template "orders/index.html" . }} </main>

<script src="/static/htmx.min.js"></script> <script src="/static/sse.js"></script> <script src="/static/ws.js"></script> </body>

2) Filtro + estado de URL

<form id="filters"
      hx-get="/orders"
      hx-target="#orders"
      hx-push-url="true"
      hx-trigger="change delay:300ms from:#status,#search">
  <select id="status" name="status">
    <option value="">Todos</option>
    <option>NUEVO</option><option>PREP</option><option>LISTO</option>
  </select>
  <input id="search" name="q" placeholder="Buscar...">
</form>

<div id="orders"> {{ template "orders/table.html" . }} </div>

3) Actualizaciones en tiempo real (SSE)

<div id="realtime"
     hx-ext="sse"
     sse-connect="/events/orders"
     sse-swap="message"></div>

4) Aceptar pedido (viaje redondo de WebSocket)

<div hx-ext="ws" ws-connect="/ws/orders">
  <table id="orders-table">...</table>

<form ws-send onsubmit="return false"> <input type="hidden" name="action" value="accept"> <input type="hidden" name="order_id" value="{{ .ID }}"> <button>Aceptar</button> </form> </div>

5) Lista de verificación QA para producción

  • Manejo de 404/401/422: Mapea códigos de respuesta a swaps o mensajes
  • CSRF: Añade token vía input oculto o hx-headers
  • Control de acceso: Los endpoints SSE y WS deben enforcar auth y scoping de tenant por conexión
  • Backpressure: Throttle de flujos SSE/WS por usuario
  • Caché: Cachea fragmentos HTML en el edge; purga en actualización
  • A11y: Asegura que las regiones intercambiadas estén en regiones live (role="status" / aria-live="polite")
  • Descargas de archivos: Usa HX-Redirect para disparar una descarga completa del navegador

---

Dónde brilla HTMX (resumen)

  • Verdad renderizada en servidor: Sin duplicar validación/lógica de vista del cliente
  • Velocidad: Runtime pequeño, sin impuesto de hidratación, tiempo real multi-transporte
  • Mejora progresiva por defecto: Enlaces/formularios boosteados funcionan incluso con JS desactivado
  • URL + historia en la que puedes confiar: Push state cuando importa, refetch en lugar de snapshot cuando es más seguro
  • Componible con herramientas pequeñas: hyperscript/Alpine para estado local donde se necesite

Dónde HTMX es la herramienta equivocada

  • Offline-first o estado de cliente pesado
  • UIs de editor complejas que son esencialmente apps de escritorio en el navegador
  • Grandes marketplaces de componentes donde necesitas SSR + CSR + hidratación + una gramática de componentes compartida—los frameworks aún ganan

---

Playbook de migración (React/Next/Nuxt → HTMX, cuidadosamente)

  1. Elige una página (ej., "Pedidos"). Renderízala del lado del servidor con tus templates existentes.
  2. Envuelve main en hx-boost, y asegura que cada enlace/formulario adentro navegue e intercambie en el objetivo principal.
  3. Reemplaza un componente a la vez con un parcial del servidor + hx-get/hx-post.
  4. Conecta la historia con hx-push-url para filtros marcables.
  5. Añade SSE para actualizaciones pasivas; usa WS solo si el cliente debe hablar de vuelta.
  6. Mantén una isla de framework donde sea verdaderamente necesario (editor rico, whiteboard). No fuerces la pureza.

---

La vista estratégica

La última década construyó motores de cliente para hacer que la web se sintiera como apps. La próxima década hará el compute fungible de nuevo: fragmentos HTML renderizados cerca de los datos, transmitidos a un cliente delgado y robusto que también puede hacer suficiente lógica local cuando sea necesario. React/Next/Nuxt/SvelteKit son ideales para problemas verdaderamente con forma de app. Pero mucho de tu producto sigue siendo documentos que cambian—formularios, tablas, listas, detalles, diálogos. HTMX mantiene esos honestos y rápidos.

Si estás empezando un proyecto pequeño o mediano en 2025, empieza con HTMX y añade una pizca de Alpine o hyperscript. Si estás construyendo una app grande, haz de HTMX el default para cada página que no demande una aplicación de cliente; reserva el framework para las partes que sí lo hacen.

Entregarás más rápido, debuggearás menos, y pasarás tu tiempo donde importa: el servidor que conoce tus datos.

---

Sobre el autor: Odd-Arild Meling ha construido aplicaciones web durante tres décadas, desde PHP renderizado en servidor temprano hasta la era completa de React/SPA y de vuelta a arquitecturas HTML-primero. En Gothar usamos HTMX con Hono en Cloudflare Workers—fragmentos renderizados en servidor en el edge, TTFB sub-50ms, cero overhead de framework. Porque la mayoría de la web sigue siendo documentos que cambian, y el servidor sigue conociendo mejor tus datos.