HTMX и AlpineJS
HTMX и AlpineJSэто две JS библиотеки, которые расширяют HTML специальными аттрибутами и позволяют писать фронтенд без SPA фреймворков.
Это альтернативы React/Vue/Angular и иже с ними. Их появление вызвано усталостью от сложной JS экосистемы и тоской по временам, когда задачи решались с помощью PHP и jQuery.
Я всю жизнь писал JSON API и SPA интерфейсы и моему мозгу трудно было переварить, зачем нужны эти библиотеки и как с ними работать. Поэтому я написал эту статью.
HTMX и AlpineJS — Кто за что отвечает?
Эти две библиотеки имеют небольшое пересечение по функционалу, но в целом решают каждая свою задачу.
HTMX — чтобы делать AJAX запросы на сервер, получать HTML и динамически обновлять страницу в нужных местах.
AlpineJS — для логики, завязанной на локальное клиентское состояние. Всякие флаги isVisible, conditional rendering и т. д. Словом, все то, что существует только на клиенте.
Еще один способ думать об этом — HTMX связывает фронтенд с базой данных (через серверной API), а AlpineJS это удобный способ иметь state на фронте и отрисовывать от него интерфейс динамически.
Server Side Rendering vs SPA
Дисклеймер: термины v1 и v2 авторские.
SSR v1 (Web 2.0, эпоха PHP)
Классический серверный рендеринг существовал еще до того, как сам этот термин стал популярен, потому что другого рендеринга то и не было.
Это когда клиент делает запрос на сервер, сервер возвращает клиенту HTML документ, клиент (браузер) полностью перерисовывает всю страницу. Пользователь ощущает «перезагрузку».
Это свойственно сайтам эпохи Web2.0, такой UX уже не считается качественным, потому
Он недостаточно отзывчив
Он не поддерживает локальное состояние — весь state хранится на сервере. Все, что вы ввели в форму, все меню которые вы открыли, все это будет сброшено, после перезагрузки страницы.
SPA (Single Page Applications, эпоха ReactJS)
Как ответ на вызовы SSR v1 и Web 2.0 появились SPA — Single Page Apps или «Одностраничные приложения».
Это запутывающее название, потому что с точки зрения пользователя, страниц на сайте (приложении, как их стали после этого называть), может быть сколько угодно много.
«Одна страница» тут в чисто техническом смысле. Имеется в виду, что отныне у нас один html‑документ (страница) и абсолютно весь интерфейс рисуется динамически через JavaScript.
Это решило 2 упомянутые проблемы SSR v1 но породило массу других. На клиенте стало намного больше логики, а вот технологии для этого адаптированы не были. Язык JavaScript был спроектирован для написания маленьких скриптов и плохо масштабировался с ростом кодовой базы.
В ответ на эти вызовы, в свою очередь, стали появлятся другие технологии, такие как TypeScript и различные сборщики вроде Webpack (и их современные аналоги), линтеры, тест раннеры, пакетные менеджеры и проч. При этом, вся эта инфраструктура была разрозненной, не имела официальной поддержки от авторов языка (как в случае с Go), и требовала maintainance от самих разработчиков.
Это привело к ситуации, что человек, который отвечает за фронтенд, также вынужден отвечать за «сборку». Инструментов, которые надо подоружить, очень много, все их надо правильно настроить, какие‑то из них периодически ломают обратную совместимость.
Короче, фронтенд стал очень сложным. И сложность эта шла не от сложности самой задачи, а от низкого качества инструментов, с которыми надо бесконечно сражаться, вместо того, чтобы просто решать задачи бизнеса.
Добавьте сюда тот факт, что в мире JS сложилась культура такая, что каждый уикенд появляется новый фреймворк, экосистема постоянно шатается и изменяется.
Все это привело к «усталости от JS» ©.
SSR v2 (эпоха NextJS)
Не буду говорить Web 3.0 так как этот термин чаще связан с децентрализацией.
Серверный рендеринг v2 не связан с усталостью от JavaScript, он решал исключительно техническую проблему — индексирование поисковиками.
Все дело в том, что когда появились SPA, поисковые краулеры еще не были адаптированы под такие сайты. Они все еще ждали, что сервер вернет им статичный HTML, а попали в ситуацию, когда в этом HTML ничего нет, и надо исполнить JavaScript, чтобы там что‑то отрисовалось.
Современные краулеры умеют с этим справляться, но серверный рендеринг все еще предпочтителен для тех, кому важно SEO. Вообще поисковая индексация сложная штука, и там много нюансов, вникать в которые мы не будем. Просто примем за факт, что
SEO <3 SSR
Получается что нам с одной стороны нужны динамичные интерфейсы SPA, с другой стороны мы хотим статичный HTMX для SEO, как если бы у нас был SSR. Что делать?
Индустрия совершила полный оборот и вернулась к серверному рендерингу, только на этот раз были использованы другие технологии.
Если раньше условный PHP сервер шел в базу данных, затем генерировал HTML через шаблонизатор и отдавал на клиент, то теперь это делал NodeJS сервер, который выполнял JS внутри HTML страницы, чтобы получить статичный HTML и отдать его на клиент. Таким образом мы могли продолжать использовать SPA фреймворки вроде React и иметь много логики на клиенте, но первичный HTML который получал браузер, уже не был пустым, а содержал какое‑то осмысленное наполнение, которое можно было проиндексировать.
HTMX и AlpineJS как лекарство от JS усталости
Чисто технически последний виток закрыл все проблемы, кроме одной — джаваскрипта все еще очень много, и на нем все еще неприятно и сложно писать. Неприятно и сложно, кстати, это не просто «вайб», а прямой урон бизнесу. Это буквально значит, что с ростом кодовой базы она изменяется все сложнее. То есть разработка стоит все дороже и дороже. Усталость конвертируется в деньги напрямую, потому что и то и другое связано с энергией.
HTMX как SSR v3
Дисклеймер: термин SSR v3 авторский
Философия HTMX:
Современный фронтенд зачастую неоправдано сложен, нам следует попытаться вернуться к истокам оригинального серверного рендеринга
На заре веба была идея Hypermedia — связывания между документами через ссылки, и браузера как движка, загружающего их. Речь идет о таких тегах как
<a>
,<form>
,<script>
,<style>
,<img>
которые могут делать запросы без написания JavaScript. К сожалению, современный веб ушел от этого и стал JS‑heavy.Возврат к чистому SSR v1 невозможен, потому что современный мир действительно требует более отзывчивым интерфейсов. Так был придуман компромисс в виде фрагментов — Пусть сервер отдает HTML как раньше, но не всю страницу, а лишь ее «фрагмент», который JavaScript может вставить/заменить точечно. В результате у пользователя перересуется лишь часть интерфейса, как если бы это было SPA. При этом это будет настоящий серверный рендеринг, со всеми его плюсами.
Так родилась JS библиотека, которая расширяет (HTMX = HTML eXtended) стандартный HTML небольшим количеством дополнительных аттрибутов и делает любые теги hypermedia, а не только формы и ссылки.
HTMX vs SPA — Сдвиг Парадигмы
К этому моменту уже должно было стать ясно, но я все же объясню, ибо мой заточенный под SPA мозг это не сразу переварил.
HTMX и SPA (React и прочие) предполагают разный подход к архитектуре приложения.
SPA: сервер отдает структурированные данные (как правило JSON), а клиент отрисовывает на основе этих данных HTML
HTMX: сервер отдает HTML, а клиент лишь вставляет/заменяет этот HTML на текущей странице
То есть логика отрисовки интерфейса перемещается с клиента на сервер.
Технически у нас есть набор HTTP endpoints которые отдают кусочки HTML и наш клиент, которые дергает эти endpoints в ответ на какие‑то браузерные события (доскролл до элемента, клик по кнопке, и прочее).
Важно: у нас нет клиентского состояния! Есть только серверное.
Мы уходим от клиентских SPA библиотек вроде React, у которых есть ветвление, циклы и прочее. Вся эта логика возвращается в шаблонизатор, прямо как в старые добрые!
При этом мы вообще не пишем JavaScript, у нас есть только HTML с небольшим количеством дополнительных аттрибутов.
Важно: HTMX это не панацея. Придется повторить, но there»s no silver bullet. У этого подхода есть минусы, и вам он может не подойти. Но об этом позже.
AlpineJS как недостающее звено
HTMX вообще никак не помогает с клиентским состоянием. Если вам нужна какая‑то чисто фронтовая логика (даже элементарно сдлать кнопку disable по какому‑то кастомному условию), вам придется писать JavaScript.
Собственно, тут у вас есть выбор:
Вернуться к SPA (и возможно SSR v2) со всеми вытекающими
Писать ванильный JavaScript без библиотек
Подключить таки библиотеку, но не полноценный требующий сборки SPA фреймворк, а что‑то проще
AlpineJS заполняет именно эту нишу. Он возвращает вам клиентское состояние и позволяет кодить чисто фронтовую логику. Теперь вы можете задизейблить эту кнопку по вашему кастомному условию. И ветвления и циклы и прочее, к чему вы привыкли в реакте.
Выглядит это при этом скорее больше как Vue, нежели React. Alpine расширяет HTML небольшим количество аттрибутов, также как и HTMX, однако, в HTMX вы вообще не пишете JS, а в случае с Alpine вам все же придется, но совсем немного. Намного меньше, чем если бы вы решили писать совсем без библиотек.
Да, нативный JavaScript на самом деле весьма низкоуровневый, как бы странно это не звучало. Его DOM API императивное и многословное, и многие базовые вещи, нужные в каждом, казалось бы, проекте, вам придется писать руками с нуля. Это не Go с его стандартной библиотекой где разработчики реально сели и подумали, какие задачи придется решать инженерам изо дня в день.
HTMX + AlpineJS vs SPA. Недостатки SSR v3
Если сравнивать этот подход с классическим SPA (или SPA + SSR на условном Next), то может показаться, что такой подход имеет сплошные преимущества. И рыбку съел, и никакую ноду в проект не затащил. Разумеется, это не так. Существуют ситуации, когда такой стек вам не подойдет, и когда вам лучше сразу смотреть в сторону условных React или Next.
Если у вас много сложной клиентской логики, которая не может быть вынесена на сервер. Гротескный пример — Figma. Это действительно намного больше «приложение», чем веб‑сайт. Высочайшая степень интерактивности и необходимость в низких задержках.
Также добавлю, хоть предыдущий пункт это косвенно покрывает, что HTMX и AlpineJS не дают вам статической типизации, какую дал бы TypeScript. Если вы хотите полного покрытия типами между клиентом и сервером, то описанный здесь стек вам не подойдет. У вас может быть типизация на уровне шаблонизатора (например Templ, если вы пишете на Go), но из HTMX вы сможете, например, делать запросы на несуществующие ендпойнты, ссылаться на несуществующие узлы DOM, и прочее. Быть может, эта проблема решена в сообществе, но это в любом случае не идет из коробки, а значит, будет уже не таким минималистичным решением. Зачем вам хотеть полного покрытия типами, уже вопрос другой. Как правило это связано с размером кодовой базы или команды. С AlpineJS ситуация абсолютно такая же.
‑-
— Если вам понравилась статья, заходите в мой телеграм канал AI Coder https://t.me/ai_coder_channel где я рассказываю, как использовать ИИ в программировании
— Мой второй канал, где я пишу про свои попытки запуска микро‑продукта https://t.me/build_saas_in_public
Комментарии (4)
Uolis
06.08.2025 09:54Как человек, много лет пушущий на htmx+hyperscript (тот же что альпайн, вид сбоку, интерактивность), могу сказать очевидное:
HTMX вполне работоспособен для одиночки-разработчика, для человека без команды, для человека пишущего и бэк (у меня это Го+его темплейты) и фронт в одно лицо.
Всё.
При любых иных условиях это древний, первобытный, ад лапши из кода фронта и бэка, на мешанине кода, который работает только пока ТЫ ЛИЧНО помнишь как он работает.
Зато в той описанной нише он прекрасен.
SerafimArts
06.08.2025 09:54Я бы ещё в списочек к HTMX и AlpineJS добавил Lit.js. Помимо состояний у кнопочек нужны и сами кнопочки (можно и button использовать, но вдруг кастомное что надо?), а чтобы нормально и красиво их изолировать - можно использовать Shadow DOM. Можно и нативно, конечно, но Lit.js, судя по их заявлениям - упрощает это дело и позволяет полифиллиться.
isumix
Сейчас эпоха offline-first PWA приложений и игр. Они работают одновременно и на десктопе, и мобиле и в браузере (причем написанные один раз адаптивной версткой). Устанавливаются как нативные приложения.
Бекенд нужен для сложных вычислений, для синхронизации между устройствами, для предоставления данных, а не для отрисовки фронтенда. Бэкенд и фронтенд лучше разделить, а фронтенд скомпилировать в статические ресурсы и положить в CDN.
Если устали от сложных фреймворков, то посмотрите в сторону Фьюзора. Он задумывался как убийца Реакта и остальных фреймворков. Простая библиотека с 2 функциями - создать и обновить DOM элемент. Всё! Стейт менеджер подключаете свой если нужен. А если не нужен можно обычные переменные использовать.
isumix
При грамотной верстке, SEO прекрасно рабоает уже с 2018 года, в том числе и для SPA приложений.