Ripple: новый TypeScript UI-фреймворк, заслуживающий внимания
Если вы проводили время в борьбе с useMemo, useCallback и багами замыканий в React, вы уже знаете о ментальной нагрузке, связанной с ручным управлением реактивностью. Ripple — новый TypeScript-фреймворк, созданный Dominic Gannaway (контрибьютор React Hooks, автор Inferno, основной мейнтейнер Svelte 5) — использует совершенно иной подход: компилировать реактивность и позволить фреймворку заниматься остальным.
Вот что делает его технически интересным.
Ключевые моменты
- Ripple — это UI-фреймворк, управляемый компилятором, который использует файлы
.rippleи генерирует детализированную логику обновления DOM — без виртуального DOM или согласования. - Его модель реактивности основана на
track()и операторе доступа@, устраняя необходимость в массивах зависимостей,useMemoилиuseCallback. - Реактивные коллекции (
#[]и#{}) позволяют прямую мутацию, которая автоматически запускает обновления UI. - Фреймворк предлагает солидный инструментарий для разработчиков (интеграция с Vite, расширение для VSCode, изолированные стили), но остаётся экспериментом на ранней стадии — достойным изучения, но пока не готовым для продакшена.
Что такое UI-фреймворк Ripple?
Ripple — это UI-фреймворк, управляемый компилятором, построенный вокруг файлов .ripple — собственного формата модулей, отличного от .tsx или .jsx. Вместо того чтобы поставлять виртуальный DOM и алгоритм сравнения во время выполнения, компилятор Ripple анализирует компоненты и генерирует детализированную логику обновления DOM, которая выполняется в рантайме.
Никакого согласования. Никаких повторных запусков компонентов. Только хирургически точные обновления именно тех узлов, которые изменились.
Результат — фреймворк, который концептуально находится между Solid (детализированные сигналы) и Svelte (вывод, управляемый компилятором), но с TypeScript, рассматриваемым как полноправный участник с самого начала — а не прикрученным постфактум.
Как работает детализированная реактивность Ripple
Модель детализированной реактивности Ripple основана на двух примитивах:
track()— создаёт реактивное значение или производное вычисление@— оператор доступа для чтения и записи отслеживаемых значений
import { track } from 'ripple'
export component Counter() {
let count = track(0)
let double = track(() => @count * 2) // автоматически производное, без массива зависимостей
<div>
<p>{@count}</p>
<p>{@double}</p>
<button onClick={() => @count++}>{"Increment"}</button>
</div>
}
Когда @count изменяется, обновляются только те узлы DOM, которые от него зависят. double пересчитывается автоматически. Никакого useMemo, никакого массива зависимостей, никаких устаревших замыканий для отладки.
Это существенно отличается от модели React, где изменения состояния запускают полное повторное выполнение компонента, и от createSignal в Solid, которому Ripple намеренно не подражает. Название track() сигнализирует о другой ментальной модели: вы объявляете отслеживаемую связь, а не вручную выстраиваете граф сигналов.
Для реактивных коллекций Ripple вводит #[] (TrackedArray) и #{} (TrackedObject), которые позволяют прямую мутацию:
const todos = #[]
todos.push({ id: 1, text: 'Write docs', completed: false }) // UI обновляется автоматически
Никаких spread-операторов. Никакого setState. Просто мутируйте и двигайтесь дальше.
Discover how at OpenReplay.com.
Developer Experience во фронтенд-фреймворке Ripple TS
Ripple поставляется с сфокусированным, но практичным набором инструментов:
- CLI-скаффолдинг:
npm create ripple my-appсоздаёт проект на Vite за секунды - Расширение для VSCode: IntelliSense, диагностика и подсветка ошибок внутри файлов
.ripple - Поддержка Prettier и ESLint: Полное форматирование и линтинг для модулей
.ripple - Изолированные стили: блоки
<style>внутри компонентов автоматически изолируются, не требуется настройка CSS Modules
Компоненты используют ключевое слово component вместо function, а шаблоны являются инструкциями, а не возвращаемыми значениями — тонкое изменение, которое даёт компилятору больше пространства для оптимизации:
component Button(props: { text: string, onClick: () => void }) {
<button onClick={props.onClick}>{props.text}</button>
}
Управление потоком использует обычный JavaScript: циклы for, блоки if/else и try/catch для границ ошибок — никакой гимнастики с .map() или компонентов-обёрток <Show>.
Что касается серверного рендеринга: документация Ripple упоминает API render (сервер) и hydrate (клиент), так что SSR является частью направления дизайна. Экосистема вокруг этого находится на ранней стадии и развивается, и это не тот фреймворк, с которым вы бы сегодня выпустили продакшен-приложение.
Заключение
Ripple — это настоящий технический эксперимент от человека с редкой родословной в разработке фреймворков. Основные идеи — ленивое реактивное вычисление, отслеживание зависимостей, управляемое компилятором, TypeScript-нативный синтаксис — стоят понимания, даже если вы никогда не напишете ни строчки кода Ripple для продакшена.
Если вам интересно, GitHub-репозиторий и документация — правильные отправные точки. Запустите Vite-стартер, создайте счётчик или небольшую форму и посмотрите, подходит ли вам эта ментальная модель.
Интересные фреймворки редко громко заявляют о себе. Они просто заставляют вас думать иначе о тех, которые вы уже используете.
Часто задаваемые вопросы
React повторно выполняет целые компоненты при изменении состояния и полагается на хуки вроде useMemo для оптимизации. Solid использует детализированные сигналы, но требует ручного создания сигналов. Ripple сочетает анализ, управляемый компилятором, с примитивом track() и оператором @, чтобы генерировать хирургически точные обновления DOM на этапе сборки, устраняя необходимость в массивах зависимостей или ручной мемоизации.
Нет. Ripple — это экспериментальный фреймворк на ранней стадии. Хотя его инструментарий включает интеграцию с Vite, расширение для VSCode и изолированные стили, экосистема всё ещё развивается. Он лучше подходит для исследования и обучения, чем для выпуска продакшен-приложений на данный момент.
TrackedArray (#[]) и TrackedObject (#{}) — это примитивы реактивных коллекций в Ripple. Они позволяют напрямую мутировать данные, используя стандартные операции вроде push или присваивания свойств, и UI обновляется автоматически. Это устраняет необходимость в паттернах иммутабельных обновлений, spread-операторах или вызовах setState, характерных для React.
Документация Ripple упоминает API render и hydrate, что указывает на то, что SSR является частью направления дизайна фреймворка. Однако история SSR всё ещё на ранней стадии. Пока нет зрелого мета-фреймворка или проверенного в продакшене SSR-пайплайна, сравнимого с Next.js или SvelteKit, доступного для Ripple.
Gain Debugging Superpowers
Unleash the power of session replay to reproduce bugs, track slowdowns and uncover frustrations in your app. Get complete visibility into your frontend with OpenReplay — the most advanced open-source session replay tool for developers. Check our GitHub repo and join the thousands of developers in our community.