Alpine.js, htmx, Stimulus и другие: лёгкий JS без React-переутомления

Современный фронтенд часто ассоциируется с React, Vue и Angular — но что, если вам не нужен виртуальный DOM, тонны зависимостей и сложная настройка? В мире Ruby on Rails существуют лёгкие альтернативы, которые отлично работают с Turbolinks и Hotwire. Давайте разберёмся, когда выбрать Alpine.js вместо Stimulus, как htmx заменяет API-запросы, и почему иногда «маленький JS» — это именно то, что нужно.


� Всё началось с jQuery… а потом стало сложно

Помните те времена, когда для анимации кнопки хватало трёх строк jQuery? Затем пришли фреймворки с виртуальным DOM, состояниями, хуками и контекстами. Всё стало мощнее… и тяжелее.

Проблема:
80% Rails-приложений не нуждаются в SPA-архитектуре, но разработчики по привычке тянут npm install react.

Решение:
Использовать «минималистичный JS», который:

  • Работает с SSR (Server-Side Rendering).
  • Не требует сборки (или почти не требует).
  • Интегрируется с Rails-views.

🧩 Кому что подходит?

Инструмент Для чего? Пример использования
Alpine.js Локальная интерактивность Раскрывающиеся меню, модалки
htmx Динамическая загрузка контента Бесшовные формы, пагинация
Stimulus Управление элементами страницы Сортировка таблиц, валидация

🌲 Alpine.js: «React на минималках»

Код примера: аккордеон

<div x-data="{ open: false }">
  <button @click="open = !open">Развернуть</button>
  <div x-show="open" x-transition>
    Содержимое аккордеона...
  </div>
</div>

Плюсы:

  • Не требует сборки.
  • Работает прямо в HTML через атрибуты (x-data, x-show).
  • Подходит для компонентов, которые не нужно переиспользовать.

Минусы:

  • Нет изоляции компонентов (всё в глобальном scope).
  • Сложно тестировать (если не выносить логику в отдельные функции).

Когда брать?
Для быстрых прототипов или если в проекте уже есть Stimulus/htmx, но нужно «добавить немного reactivity».


🧩 htmx: AJAX без JavaScript

Пример: подгрузка комментариев

<button hx-get="/comments" hx-target="#comments-list">
  Загрузить комментарии
</button>
<div id="comments-list"></div>

Плюсы:

  • Сервер рендерит HTML, клиент только вставляет его в DOM.
  • Поддержка WebSockets (через SSE).
  • Можно комбинировать с Turbo Streams.

Минусы:

  • Требует серверной логики для рендеринга частичных шаблонов.
  • Не подходит для сложного клиентского состояния.

Когда брать?
Если вы хотите заменить fetch(...).then(...) на что-то более декларативное.


🎮 Stimulus: «jQuery на стероидах»

Пример: кнопка «Нравится»

// Контроллер
import { Controller } from "@hotwired/stimulus"

export default class extends Controller {
  static targets = ["counter"]
  
  like() {
    fetch("/likes", { method: "POST" })
      .then(response => response.json())
      .then(data => this.counterTarget.textContent = data.count)
  }
}
<div data-controller="likes">
  <button data-action="likes#like">❤️</button>
  <span data-likes-target="counter">0</span>
</div>

Плюсы:

  • Чёткое разделение HTML и логики.
  • Интеграция с Webpack (если он у вас есть).
  • Легко тестировать (это просто классы JavaScript).

Минусы:

  • Требует настройки сборки (если не используете импорты через importmap).
  • Избыточен для простых операций.

Когда брать?
Для проектов, где нужно много JS, но не хочется тянуть React.


💥 Антипаттерны

  1. Смешивать Alpine.js и Stimulus
    Они решают разные задачи. Alpine — для reactivity, Stimulus — для структуры.

  2. Использовать htmx для всего
    Если у вас сложный UI с состоянием (например, drag-and-drop), лучше взять Stimulus.

  3. Писать на Alpine.js сложную логику
    Как только в x-data появляется { users: [], pagination: {...} } — пора переходить на Stimulus.


🧪 Тестирование

Alpine.js:
Пишите интеграционные тесты (например, Capybara), потому что логика привязана к DOM.

Stimulus:
Можно тестировать контроллеры изолированно (Jest/Vitest).

htmx:
Тестируйте серверные эндпоинты (RSpec), а клиентскую часть — через системные тесты.


🎤 Что сказать на собеседовании

— Почему вы не используете React/Vue?

— Наш проект строится вокруг SSR, и нам достаточно Stimulus для интерактивности. Зачем тянуть лишние зависимости, если Rails уже даёт Turbolinks и Turbo Streams?


🏁 Вывод

Выбирайте инструмент под задачу:

  • Нужно быстро добавить анимацию? Alpine.js.
  • Заменить AJAX-запросы? htmx.
  • Построить структурированный фронтенд? Stimulus.

Главное — не переусложнять. Иногда «лёгкий JS» — это именно то, что сделает ваш Rails-проект быстрым и поддерживаемым.

🗓 Дата публикации: 27.01.2025, но это не точно...

Ruby on Rails JavaScript Frontend Alpine.js htmx Stimulus javascript JS