Micra.js — лёгкий реактивный фреймворк для простых сайтов

·

Я помню время когда jQuery был UI-библиотекой для работы с DOM по умолчанию. Потом появился Knockout.js, Backbone.js и так мы дошли до React/Vue/Svelte. Фронтенд стал сложнее. Но такая сложность нужна не всегда. В мире всё ещё существуют простые сайты, состоящие из нескольких страниц, небольшие SaaS, панели управления и блоги. Часто таким решениям не требуется большой и сложный фронтенд. И в этом случае тоже приходится думать с помощью какого инструмента решать задачу создания интерфейса. В своих проектах я пробовал разные подходы — от Vanilla.js до React-а и всё пытался подобрать удобное решение, позволяющее совместить в себе реактивность и возможности взаимодействия с DOM и поддержку серверного рендеринга. А еще для простых сайтов не хочется тянуть кучу зависимостей. Иногда достаточно просто подключить библиотеку извне.

Так в ходе поиска баланса я набросал Micra.js — небольшую UI библиотеку на 5 Kb. Она имеет свои плюсы и минусы, абсолютно неуникальна и не претендует на звание заменителя всех других библиотек. Скорее это сборник практик, которые сформировались в единое решение.

Что это и как работает

Micra.js — это лёгкий реактивный фреймворк, который работает через shallow‑Proxy, отслеживая только верхний уровень state. Любое изменение top‑level свойства вызывает ререндер, а вложенные объекты нужно заменять целиком. Все синхронные обновления состояния батчатся в один microtask, поэтому несколько записей приводят к одному ререндеру. При первом рендере Micra сканирует DOM, собирает директивы (data-text, data-if, data-model и др.) и кэширует их, чтобы последующие обновления были быстрыми и не требовали повторного обхода дерева.

Выражения в директивах выполняются через быстрый путь для простых обращений к свойствам или через компиляцию с глобальным кэшем для сложных выражений. Внутри выражений доступен расширенный exprState, включающий методы компонента и хелперы (prop, emit, fetch). Списки с data-each и data-key обновляются через keyed‑diff: переиспользуются существующие DOM‑ноды, создаются только новые, а исчезнувшие удаляются. Каждый data-component создаёт независимый инстанс со своим состоянием, методами, props из data-* и собственным жизненным циклом. Компоненты общаются через event bus, а доступ к конкретному экземпляру возможен через Micra.instances().

Как видите, ничего нового и уникального. Некоторые решения компромиссны. Например, проксирование top-level. Для решений типа "показать модалку", "отфильтровать таблицы" выглядит достаточно. Меньше багов, выше производительность, так как нет лишних обходов. Но я не исключаю, что позже приду необходимости deep‑proxy.

В то же время, я собрал сборник рецептов и набор компонентов, которые можно копировать и использовать. В качестве эксперимента, хочу попробовать обучить AI использовать Micra.js в качестве замены React. Задачка, конечно, требует времени, потому что кодовая база с React огромна. В то же время, это не всегда играет на руку. Примеры кода могут быть и хорошими и плохими и корректировка достигается с помощью правильный скиллов и гайдлайнов. И я думаю, что если это можно сделать с одной библиотекой, то можно и с другой.

Обычный день

·

Мы тут с моим приятелем Клодом решили, что надо развивать мой личный бренд. А ничто так не развивает бренд и не укрепляет доверие, как рассказ про себя в обычный день. И раз уж так вышло, что сегодня воскресенье, то и рассказывать придется именно по него.

Сегодня встал на удивление поздно. То ли погода так повлияла, то ли вчерашняя тренировка, но проснулся я в половину девятого. Обычно я встаю в семь. А сегодня припозднился. Проснись я в это время в обычный день, я бы испытывал ужасный дискомфорт. "Все проспал". Но по воскресеньям, я считаю можно. Потому что я убежден, что воскресенье должен быть ленивым. Можно делать всё, что хочется, и не делать, если не хочется.

Поэтому сегодня я приготовил завтрак, обед и даже испёк сдобную булку. И с абсолютно спокойной душой решил пропустить длительную тренировку, променяв ее на чтение книжки в парке.

Такое, конечно, бывает не каждое воскресенье. Иногда я все таки бегаю длительные и чаще всего не пеку булки. Но вот идея ленивого дня и ощущения, что сегодня можно без четкого плана и "как пойдет" живет держится в моем сознании как римская империя.

Нельзя просто взять и сгенерировать тему

·

В рамках работы над open-source проектом работал над задачкой по генерации тем. То есть в проекте было несколько тем: одни темы имели светлый и темный режим, другие - только светлый или только темный. И задача сводилась к тому, чтобы сделать для всех тем светлый и темный режим.

20260429_090506_ae78eb.webp

Вот на скриншоте показаны несколько темных тем: Dracula, Solarized, Gruvbox, Monokai, Moonlight. В теории можно взять и инвертировать светлоту, получив тем самым светлую тему. В теории теория и практика не отличаются. На практике всё совсем наоборот 😀. Чтобы объяснить почему, полезно сначала посмотреть на то, как устроена работа с цветом в принципе.

Читать далее →

Про подключение Garmin MCP к Claude Code и забег в Бечее

·

На днях с подачи приятеля подключил Garmin MCP к Claude Code. Опыт интересный. В первую очередь, потому что все эти данные мне и так известны и доступны в виде сухой статистики в Garmin Connect. Хотелось попробовать новый опыт взаимодействия.

20260328_202912_0a7bbc.webp

Читать далее →

TrueNorth для ясности в делах

С декабря прошлого года работаю над парой проектов, которые идут рука об руку. Про первую вкратце писал в итогах прошлого года. Про вторую не говорил, потому что показать было нечего. Теперь вот есть — TrueNorth

20260118_132929_a4d078.webp
TrueNorth Dashboard

Читать далее →

Итоги 2025-го года

·

Добавим к итогам в копилку итогов ещё один год. Об итогах 2024 можно почитать по ссылке.

Как обычно, мне изначально казалось, что тут и говорить не о чем. Пока не начал разматывать клубок воспоминаний.

Про бег

В этом году я бегал. Не так много, как в прошлом, но всё же.

Участвовал в благотворительном забеге в Паличе
Сбегал почти марафон в Иванице
Был на Дрине
Участвовал в ночном марафоне по городу
— А ещё сбегал ночной трейл на Фрушке
— Ещё была Белградская 10-ка
— И ночной трейл на Авале, который мы скорее прошли, чем пробежали, с сыном.

Личные проекты

— Летом сделал календари.

20251231_142101_633c7a.webp

Идея так зашла местной типографии, что они даже выпустили свою версию по моим макетам — до сих пор улыбаюсь, вспоминая это. Но главное не в этом. Часть календарей я продал, часть просто раздаю.

В каждом месяце — фотография, которую я сделал именно в тот период, когда она и должна быть: январь — из январского дня, июль — из июльского, и так далее. Получился такой маленький визуальный дневник года.

— Осенью запустил syn-co.me, который помогает координировать работу команды в разных часовых поясах. Писал о нём вот тут — Координатор по часовым поясам.

— Почти запустил, но ещё не совсем, STRATA. Проект пока в бете. Всё работает, но домен я ещё не покупал, и мелкие огрехи вроде оформления страницы «О проекте» требуют полировки.

Суть проекта — посмотреть на то, как тратится ваше личное время. Без давления, без громкого «будь продуктивнее, выше, сильнее». Просто честный взгляд на то, куда уходит день. В основе лежит методология PARA, точнее её часть — areas. День можно разбить на повторяющиеся действия, посчитать их и увидеть, из каких слоёв состоит ваш день, неделя, жизнь.

Приходите тестировать STRATA. Всё работает без регистрации и SMS. Но регистрация позволит хранить данные и пользоваться таймером с любого устройства.

20251231_135936_d8b74e.webp

Как обычно, много работал, а к концу года стал открыт к новым предложениям, возможностям и вызовам 😁.

Про увлечения

Много писал в блокнотик и иногда рисовал.

20251231_140435_122af6.webp

Про блокнот хочу сказать отдельно. В этом году я избавился почти ото всех электронных таск-трекеров и систем заметок — и заменил всё бумагой. За полгода исписал один блокнот и начал второй. Ещё вспомнил о своей любви к перьевым ручкам. Пользовался ими ещё в детстве: в старших классах у меня была перьевая ручка, которой я писал постоянно.

Сейчас у меня появился небольшой зоопарк ручек и чернил. Рассказ о них, возможно, потянет на отдельный пост.

Ещё в этом году удалось перевезти гитару. Спасибо всем причастным — мы не виделись с этой крошкой почти три года.


Год снова получился насыщенным. Были и сложности, и радости, но главное — движение вперёд. Впереди новый сезон, новые старты и новые вызовы.

Друзья, с наступающим вас 🎄 Спасибо, что были рядом весь этот год — на забегах, в путешествиях, в комментариях и личных сообщениях. Каждая встреча, каждый разговор делали этот год особенным. Пусть в новом году у каждого из вас будет больше поводов для улыбок, интересных маршрутов и классных достижений. До встречи в 2026-м! ✨

Что не так с совеременной почтой?

·

Почта давно перестала быть простым (и возможно удобным) инструментом. В череде изменений интерфейса в Gmail, в чехарде перепрыгиваний с одной почты на другую, я перестал доверять почтовому сервису.

Даже если сервис предоставляет возможность подключения собственного домена, на сегодняшний день этого недостаточно.

Читать далее →

Координатор по часовым поясам

·

Чуть ранее я писал, что ищу новый проект, к которому мог бы присоединиться как разработчик или engeneering manager. Пока же общаюсь с разными компаниями, есть время и на свои проекты. Сегодня, к примеру, рассказывал о своем проекте в одном классном сообществе.

Что такое syn-co.me?

Работая в распределенных командах, я заметил проблему поиска удобного времени для созвона. В маленькой команде может отсутствовать бюджет на корпоративные инструменты вроде MS Teams. Даже если есть Teams, не всегда удобно договариваться о встрече.

Поэтому я создал инструмент, позволяющий довольно быстро найти точки пересечения временных зон коллег с учетом их рабочих часов.

Почему это критично?

Представьте сценарии, в которых я работал:

Сценарий 1: Глобальная команда с экстремальной разницей во времени

Нужно найти время для встречи: разработчик в Токио (9:00–18:00), дизайнер в Берлине (8:00–17:00), менеджер проекта в Сан-Франциско (9:00–18:00) и контент-менеджер в Дубае (8:00–16:00).

Разница во времени между крайними точками — 16 часов. Пересечение всего 1–2 часа в день.

Вручную считать это — занимает минут 10–15. А если встреч в день 3-4? Вот уже потеряно час времени на одну координацию.

20251202_130732_b265ab.webp

Посмотреть пример


Сценарий 2: Фриланс команда с асинхронными часами

Четыре фрилансера, каждый работает в своем ритме:

  • Фрилансер 1: 6:00–14:00 (ранний старт)
  • Фрилансер 2: 10:00–22:00 (обеденная смена)
  • Фрилансер 3: 14:00–23:00 (вечерний график)
  • Фрилансер 4: 16:00–00:00 (ночной сервис)

Найти окно, когда все четверо онлайн одновременно — это практически головоломка. Часто просто невозможно.

20251202_130833_4c7f2b.webp

Посмотреть пример


Сценарий 3: Частично удалённая команда (гибридная боль)

Офис находится в Москве (9:00–18:00), но есть:

  • разработчик в Австралии (работает 18:00–02:00 по московскому времени — ночью!)
  • стажер в Индии (12:00–20:00 московского)
  • два офисных сотрудника (9:00–18:00)

Все нужны на одном созвоне. Но когда? Австралиец уже спит, когда просыпается Московский офис. Индиец работает, но только 3-4 часа пересекаются со всеми остальными.

20251202_130927_12d6de.webp

Посмотреть пример


Сценарий 4: Асинхронные часы в одном часовом поясе

Все в одном городе (например, Москве), но разные рабочие графики:

  • "Жаворонок" работает 6:00–14:00
  • "Нормальный" сотрудник 10:00–18:00
  • "Сова" 14:00–22:00

На первый взгляд просто, но окна пересечения очень узкие. Часто получается, что единственный момент, когда все три свободны — это 14:00, и то 4 часа.

20251202_131101_5d8939.webp

Посмотреть пример


Сценарий 5: А вот стартап-команда из 10 человек

Пример, одной из команд в которой я когда-то работал — 10 человек из 10 разных городов:

Денис (Белград) 9–18
Александр (Москва) 9–18
Эмма (Лондон) 9–18
Джеймс (Сингапур) 9–18
София (Нью-Йорк) 9–18
Юки (Токио) 9–18
Лиза (Берлин) 9–18
Маркус (Лос-Анджелес) 9–18
Анна (Варшава) 8–17
Дэвид (Дубай) 7–16
Изабелла (Рим) 10–19

Все одновременно работают 9-18 — вроде просто. Но разница во времени между Лос-Анджелесом и Токио — 17 часов. Окно пересечения при такой разнице буквально 1-2 часа в день. А если кто-то берет выходной или уходит на обед — окно сжимается еще больше.

Посмотреть пример


Как это решает syn-co.me?

Вы просто добавляете имена коллег, их часовые пояса и часы работы. На одном экране видите 24-часовую шкалу для каждого. Синяя полоса — это рабочее время, серая — спят или не работают.

За 10 секунд видно, где пересекаются все — вот и время встречи.

Никаких гугления таблиц часовых поясов. Никаких "подождите, в Токио сейчас сколько?". Просто визуально видите.


Результаты

20251202_125333_67deb8.webp

За последний месяц сервис использовали 655 уникальных пользователей из разных стран:

  • 🇺🇸 51% — США
  • 🇩🇪 Германия
  • 🇬🇧 Великобритания
  • 🇫🇷 Франция
  • 🇷🇸 Сербия
  • и другие страны

20251202_125403_d86191.webp

Часть людей, используют сервис не напрямую, а через синхронизацию в Confluence. Пока сервис существует недолго, но меня определенно радует текущая динамика. В моем бэклоге еще много идей, а после сегодняшнего митапа их стало еще больше. Если вы работаете в распределённой команде и устали от координации встреч — попробуйте syn-co.me. Это займет 30 секунд.

Нам нужно поговорить о браузерах

·

Вчера листая ленты bsky наткнулся на анонс — релиз еще одного браузера.

20251129_082205_23bbc8.webp

Сначала подумал "ну выпустили и выпустили", а потом решил глянуть что там под капотом. Буквально несколько дней назад я вновь экспериментировал с браузерами, переключившись с Firefox на Brave, а потом назад. Уже не помню сколько лет я использую фокс. Кажется, еще с версии 3.5, а может и раньше, периодически переключаясь на другие браузеры, чтобы изучить их опыт использования. И вот на протяжении всех этих долгих лет использования должен сказать, что на фоксе все хорошо. Работает он понятно, предсказуемо и все еще придерживается идеи о приватности личных данных. Как всегда, не хватает оптимизаций вроде экономии батареи. Но жить с этим можно.

Читать далее →

Как найти удобное время для встречи, когда команда разбросана по миру

·

Недавно добавил на Syn-co.me новую функцию — поиск удобного времени для встреч. Если вы уже пользовались сайтом, то знаете: он показывает время всей команды на одном таймлайне. Просто добавляете участников с их часовыми поясами, и сразу видно, кто работает, кто спит, кто только проснулся.

Теперь при добавлении участников из разных городов, а алгоритм предлагает, когда лучше всего созвониться. Причем не просто "когда все не спят", а когда время действительно удобное для всех. Или хотя бы максимально справедливое, если идеального варианта не существует.

20251016_075043_f3deed.webp

Проблема

Представьте: ваш коллега в Токио, партнер в Нью-Йорке, а вы в Москве. Когда в Москве 14:00 (отличное время для звонка), в Нью-Йорке 6 утра (кто-то еще спит), а в Токио уже 20:00 — конец рабочего дня.

Можно, конечно, открыть мировые часы и начать перебирать: "А если в 10 утра по Москве? Нет, подождите, тогда в Токио будет..." Через пять минут такой арифметики голова идет кругом.

Как это работает

Алгоритм проверяет каждые полчаса в ближайшие два дня и оценивает, насколько удобно это время для каждого участника. Не все часы одинаково хороши для встреч.

Оптимальное время — середина рабочего дня, примерно с 10 до 16 часов. Люди уже проснулись, выпили кофе, разобрали почту. Максимальная продуктивность.

Хорошее время — начало или конец рабочего дня. С 9 до 10 утра или с 16 до 17 вечера. Можно созвониться, но кто-то может быть не в лучшей форме.

Приемлемое время — чуть за границами обычного расписания. Например, 8:30 утра или задержаться до 18:00. Неудобно, но терпимо.

Некомфортное время — приходится серьезно менять планы. Встать пораньше в 7 утра или остаться после работы до 19:00. Такие встречи лучше избегать, но иногда выбора нет.

Алгоритм выбирает варианты, где всем хотя бы приемлемо, и сортирует их от лучших к худшим.

20251016_075109_ecec26.webp

Что делает время действительно удобным

Тут начинается самое интересное. Я бы выделил три столпа на которых основана логика алгоритма.

Справедливость важнее общего удобства. Лучше, когда всем "хорошо", чем когда двоим "отлично", а одному "ужасно". Поэтому алгоритм в первую очередь смотрит на того, кому хуже всего. Если есть вариант, где минимальный комфорт выше — он побеждает.

Чем раньше, тем свежее. Потому что ранние встречи обычно продуктивнее поздних. Хотя и всё индивидуально, но обычно к вечеру люди устают, думают о доме, концентрация падает. При прочих равных алгоритм предпочитает утренние варианты.

Избегаем экстремальных часов. Никто не хочет созваниваться в 5 утра или в 11 вечера. Такие варианты получают серьезный штраф. Также учитывается обеденное время — встреча с 12 до 13 нравится немногим.

Гибкость как параметр

Иногда нужно быстро найти время, и все готовы немного подвинуть свое расписание. Иногда важно никого не беспокоить вне рабочих часов.

Поэтому в инструменте есть параметр гибкости — от 0 до 12 часов. С нулевой гибкостью алгоритм ищет только время в пределах рабочих часов. С гибкостью в 3-4 часа появляются варианты, где кто-то начинает чуть раньше или задерживается. Чем выше гибкость, тем больше вариантов, но тем менее комфортными они становятся.

Когда компромиссы неизбежны

Иногда приходится признать: идеального времени нет. Если участники размазаны по всему миру, кому-то точно будет неудобно.

Для Москвы, Нью-Йорка и Токио практически невозможно найти время, когда всем комфортно. Разница часовых поясов слишком велика. В таких случаях алгоритм предлагает несколько вариантов с разными компромиссами.

Может быть, один раз неудобно будет Токио, в следующий раз — Нью-Йорку. Справедливость можно обеспечить не за одну встречу, а в серии созвонов.

Про Syn-co.me

20251016_075151_e87e85.webp

Инструмент работает прямо в браузере. Никаких регистраций, никаких серверов, никакого сбора данных. Вся информация о команде кодируется в URL — можете сохранить в закладки или отправить коллегам.

Изначально Syn-co.me создавался как простой таймлайн часовых поясов команды. "Stop doing timezone math in your head" — главная идея. Поиск времени встреч — логичное продолжение: показывать не просто "когда все свободны", а "когда всем будет действительно удобно".

Казалось бы, мелочь — подобрать время для звонка. Но эти мелочи съедают время и нервы. Особенно когда участников больше двух и часовые пояса разбросаны. Возможно, я слишком много думаю про расписания. Но когда постоянно работаешь с людьми из разных часовых поясов, начинаешь ценить инструменты, которые просто работают и не требуют усилий.