Я помню время, когда jQuery стоял почти на каждом сайте. Тогда еще не было фреймворков и jQuery был простым способом дотянуться до DOM: навесить обработчик, что-то показать, что-то спрятать, дёрнуть запрос. Тогда это решало большинство задач. Потом фронтенд стал сложнее. Во многом по делу, потому что приложения выросли, и React, Vue, Svelte выросли вместе с ними. Но такая сложность нужна не всегда.
Осталось много проектов, где сервер уже отдаёт готовую HTML-разметку, а на клиенте требуется лишь немного реактивности: открыть модалку, обновить счётчик, отфильтровать таблицу, переключить вкладку. Разворачивать ради этого полноценный фреймворк со сборкой и роутингом часто не хочется. А писать на чистом JavaScript быстро становится неудобно, когда нужно отслеживать состояние и синхронизировать его с DOM.
Я искал решение, которое даёт реактивность, но при этом остаётся максимально лёгким и не требует отдельного билда. Хотелось просто подключить скрипт к уже существующей серверной разметке — и чтобы она начала реагировать на изменения состояния.
Основная идея
Micra позволяет сделать HTML, который пришёл с сервера, реактивным. Ты описываешь поведение в обычном JavaScript-объекте, а в разметке используешь простые data-атрибуты и директивы.
Вот как это выглядит:
<div data-component="modal">
<button @click="open">Открыть диалоговое окно</button>
<div data-show="isOpen">
<div class="backdrop" @click="close"></div>
<div role="dialog" aria-modal="true">
<h2>Пример диалогового окна</h2>
<button @click="close">Закрыть</button>
</div>
</div>
</div>
А поведение описывается обычным JS-объектом — методами и состоянием без отдельного слоя представления:
Micra.define("modal", {
state: {
isOpen: false,
},
open() {
this.state.isOpen = true;
},
close() {
this.state.isOpen = false;
}, // data-show прячет и показывает сам
});
Micra.start(); // найти на странице data-component и поднять их
Нажали кнопку — open() ставит isOpen = true, и блок с data-show="isOpen" появляется. Клик по «Закрыть» или по фону зовёт close() — он закрывает блок. Никаких ручных поисков элементов по querySelector и манипуляций со стилями. Изменилось только состояние, остальное взяла на себя библиотека.
В этом вся идея. Ты пишешь обычный HTML. Не нужно держать в голове дерево, выцеплять узлы по селекторам и руками сводить их с состоянием. Классы остаются тем, чем были, — для стилизации. А data-атрибуты говорят, что на этом куске разметки происходит: data-component — где живёт компонент, data-show — когда его показывать, @click — что вызвать по клику. Поведение описано прямо в разметке, а сама разметка остаётся читаемым HTML.
Самое сложное — вовремя остановиться
Когда я начал делать Micra, самым трудным оказалось не придумать, что добавить, а понять, что не нужно добавлять. Хотелось сделать "по-взрослому": добавить роутер, глубокую реактивность, систему компонентов, свой язык в директивах. Каждый раз, когда возникала такая мысль, я возвращался к изначальной цели — сделать маленькую библиотеку, которую можно просто подключить к существующей серверной разметке.
Ограничение в ~7 КБ оказалось очень полезным дисциплинирующим фактором. Пока ты в него вписываешься, ты физически не можешь превратить инструмент в очередной фреймворк.
Поэтому в Micra сознательно нет:
- Клиентского роутинга
- Глубокой реактивности с вложенными объектами
- Своей системы компонентов
- Сложного DSL внутри атрибутов
Всё это можно добавить позже (или не добавлять вообще). Главное — не раздувать библиотеку ради "полноты".
Для кого Micra
Micra — это не замена React, Vue или даже Alpine.js. Это инструмент для тех случаев, когда тебе нужна реактивность, но ты не хочешь тащить за собой тяжёлый инструментарий.
Она хорошо подходит для:
- Админ-панелей и внутренних инструментов
- Небольших SaaS
- Сайтов, где основная разметка генерируется на сервере (Rails, Laravel, Django, WordPress и т.д.)
- Ситуаций, когда хочется быстро добавить интерактивность без отдельного фронтенд-приложения
Если проект требует сложного клиентского состояния, клиентского роутинга и тяжёлой логики — лучше взять полноценный фреймворк. Micra для этого не предназначена.
Я не претендую на то, что придумал что-то революционное. Micra выросла из набора практик, которые я использовал сам, и просто оформилась в отдельную библиотеку. Если тебе удобнее работать с htmx, Stimulus, Alpine или чем-то другим — используй то, что лучше ложится на твои задачи.
Micra лежит на micrajs.dev, исходники под MIT.