Powrót do korzeni — HTML jako interfejs
Przez ostatnią dekadę budowanie aplikacji webowych zdominowały frameworki JavaScript — React, Vue, Angular. Każdy nowy projekt wymagał konfiguracji bundlera, zarządzania stanem, routingu po stronie klienta i API w formacie JSON. Dla wielu aplikacji to nadmierna złożoność.
HTMX proponuje radykalnie inne podejście: zamiast budować API zwracające JSON i renderować HTML w przeglądarce, serwer zwraca gotowe fragmenty HTML, a HTMX podmienia je na stronie. To powrót do modelu, w którym serwer kontroluje interfejs — ale z dynamicznością, którą wcześniej dawał tylko JavaScript.
Jak działa HTMX?
HTMX to biblioteka JavaScript o rozmiarze zaledwie 14 KB (minified + gzipped), która rozszerza HTML o nowe atrybuty. Dzięki nim każdy element HTML może wysyłać żądania HTTP i aktualizować fragmenty strony bez pełnego przeładowania.
Podstawowy przykład — przycisk ładujący treść:
<button hx-get="/api/wiadomosci"
hx-target="#lista-wiadomosci"
hx-swap="innerHTML">
Załaduj wiadomości
</button>
<div id="lista-wiadomosci"></div>
Po kliknięciu przycisku HTMX wysyła żądanie GET do /api/wiadomosci, a odpowiedź (fragment HTML) wstawia do elementu #lista-wiadomosci. Żadnego JavaScriptu — cała logika wyrażona jest w atrybutach HTML.
Kluczowe atrybuty HTMX
Żądania HTTP
hx-get— żądanie GEThx-post— żądanie POSThx-put— żądanie PUThx-delete— żądanie DELETE
Cel i sposób wstawienia
hx-target— selektor CSS elementu, który zostanie zaktualizowany (domyślnie: element z atrybutem)hx-swap— jak wstawić odpowiedź:innerHTML,outerHTML,beforeend,afterbegin,delete
Wyzwalacze
hx-trigger— zdarzenie uruchamiające żądanie:click,submit,keyup,load,revealed(element pojawił się w viewport)
Przykład formularza
<form hx-post="/kontakt"
hx-target="#formularz-kontener"
hx-swap="outerHTML">
<input type="text" name="imie" placeholder="Imię" required>
<input type="email" name="email" placeholder="Email" required>
<textarea name="wiadomosc" placeholder="Wiadomość" required></textarea>
<button type="submit">Wyślij</button>
</form>
Serwer po przetworzeniu formularza zwraca HTML z potwierdzeniem, który zastępuje cały formularz. Bez przekierowania, bez przeładowania strony.
Server-driven UI
HTMX promuje architekturę server-driven UI — serwer jest jedynym źródłem prawdy o stanie interfejsu. To fundamentalna zmiana w porównaniu z podejściem SPA, gdzie stan aplikacji zarządzany jest po stronie klienta.
Zalety tego podejścia:
- Brak duplikacji logiki — walidacja, autoryzacja i renderowanie odbywają się w jednym miejscu (serwerze)
- Prostszy stack technologiczny — nie potrzebujesz osobnego API JSON, routingu klienta, zarządzania stanem
- Łatwiejsze debugowanie — odpowiedź serwera to gotowy HTML, który można podejrzeć w narzędziach przeglądarki
- Bezpieczeństwo — logika biznesowa nie jest eksponowana w kodzie JavaScript dostępnym w przeglądarce
HTMX z Go — naturalne połączenie
HTMX szczególnie dobrze współgra z językami serwerowymi, które mają silne wsparcie dla szablonów HTML. Go z pakietem html/template jest tutaj idealnym przykładem:
func handleWiadomosci(w http.ResponseWriter, r *http.Request) {
wiadomosci := pobierzWiadomosci()
// Dla żądań HTMX zwracamy sam fragment
if r.Header.Get("HX-Request") == "true" {
tmpl.ExecuteTemplate(w, "lista-wiadomosci", wiadomosci)
return
}
// Dla zwykłych żądań zwracamy pełną stronę
tmpl.ExecuteTemplate(w, "strona", wiadomosci)
}
Nagłówek HX-Request pozwala rozróżnić żądania HTMX od zwykłych żądań przeglądarki. Ten sam endpoint może obsługiwać oba scenariusze — zwracając fragment HTML dla HTMX lub pełną stronę dla bezpośredniego wejścia.
Zaawansowane możliwości
HTMX oferuje znacznie więcej niż podstawowe żądania:
Wyszukiwanie w czasie rzeczywistym:
<input type="search"
name="q"
hx-get="/szukaj"
hx-target="#wyniki"
hx-trigger="keyup changed delay:300ms"
placeholder="Szukaj...">
Żądanie wysyłane jest 300 ms po ostatnim naciśnięciu klawisza — klasyczny debounce bez linijki JavaScriptu.
Nieskończone przewijanie:
<div hx-get="/artykuly?strona=2"
hx-trigger="revealed"
hx-swap="afterend">
Ładowanie...
</div>
Gdy element pojawi się w viewport, automatycznie ładowana jest kolejna strona wyników.
Wskaźniki ładowania:
<button hx-get="/dane" hx-indicator="#spinner">
Pobierz dane
<span id="spinner" class="htmx-indicator">⏳</span>
</button>
HTMX automatycznie pokazuje i ukrywa wskaźnik ładowania podczas trwania żądania.
Kiedy HTMX, a kiedy SPA?
HTMX sprawdzi się, gdy:
- Budujesz aplikację z przewagą formularzy i wyświetlania danych
- Zespół ma doświadczenie głównie w technologiach serwerowych
- Priorytetem jest prostota i szybkość wdrożenia
- SEO jest ważne (serwer renderuje pełny HTML)
- Aplikacja nie wymaga skomplikowanych interakcji po stronie klienta
SPA będzie lepszym wyborem, gdy:
- Budujesz aplikację z bogatymi interakcjami w czasie rzeczywistym (edytor graficzny, gra)
- Potrzebujesz zaawansowanego zarządzania stanem po stronie klienta
- Aplikacja musi działać w trybie offline z synchronizacją danych
- Budujesz aplikację mobilną przez React Native lub podobne rozwiązanie
Podsumowanie
HTMX to nie krok wstecz — to przemyślana odpowiedź na nadmierną złożoność współczesnego frontendu. Dla dużej części aplikacji webowych — stron firmowych, paneli administracyjnych, dashboardów, CRM-ów — podejście server-driven z HTMX jest prostsze, szybsze w implementacji i łatwiejsze w utrzymaniu niż pełnoprawne SPA. Nie eliminuje potrzeby istnienia frameworków JavaScript, ale pokazuje, że wiele problemów można rozwiązać prościej, gdy serwer zwraca HTML zamiast JSON.