Fresh — фреймворк для Deno, основанный на Preact и архитектуре island-components. Несмотря на использование Preact вместо React, большая часть экосистемы React-библиотек может применяться напрямую или с минимальной адаптацией. Это достигается благодаря высокой степени совместимости API и поддержке JSX, хуков и контекста.
Ключевой особенностью является отсутствие этапа сборки и ориентация на серверный рендеринг с выборочной гидратацией. Это напрямую влияет на способы подключения и использования сторонних библиотек.
Fresh использует Preact в режиме compat, что позволяет
импортировать библиотеки, ожидающие React API.
Основные моменты совместимости:
preact/compat реализует интерфейсы react и
react-domuseState, useEffect,
useContext, useReducer и др.В Fresh настройка алиасов уже выполнена на уровне runtime, поэтому ручная конфигурация, как в Webpack или Vite, не требуется.
Fresh работает исключительно с ES-модулями и URL-импортами. React-библиотеки подключаются через CDN, поддерживающие ESM.
Пример источников:
esm.shskypack.devcdn.jsdelivr.netИмпорт выполняется напрямую в файлах компонентов:
import { useForm } from "https://esm.sh/react-hook-form";
Особенности такого подхода:
node_modulesБольшинство популярных UI-библиотек для React применимы во Fresh.
Material UI использует Emotion и требует корректной работы с SSR. Во Fresh допустимо использование, но с учётом ограничений:
Пример импорта:
import Button from "https://esm.sh/@mui/material/Button";
Ant Design ориентирован на браузерную среду и крупный bundle. Использование возможно, но противоречит философии Fresh:
Подходит для изолированных административных интерфейсов.
Наиболее естественный вариант для Fresh — headless-подход.
Пример:
import * as Dialog from "https://esm.sh/@radix-ui/react-dialog";
Fresh не навязывает систему управления состоянием. Возможны несколько подходов.
Использование useState и useReducer внутри
island-компонентов — основной и предпочтительный вариант.
Zustand хорошо подходит благодаря минимализму и отсутствию жёсткой привязки к React internals.
import { create } from "https://esm.sh/zustand";
Особенности:
Использование возможно, но не рекомендуется:
Одна из наиболее совместимых библиотек:
import { useForm } from "https://esm.sh/react-hook-form";
Работает, но менее эффективен:
Framer Motion использует сложные DOM-манипуляции и не всегда стабилен в Preact-окружении. Использование возможно, но ограничено:
@preact/signals для реактивных переходовFresh имеет встроенную файловую маршрутизацию. Использование React Router или аналогов нецелесообразно:
React-библиотеки, ожидающие наличие роутера, должны использоваться без их routing-части либо с адаптацией.
Контекст работает в пределах island-дерева. Глобальные провайдеры, оборачивающие всё приложение, противоречат архитектуре Fresh.
Рекомендуемый подход:
react-dom/client напрямую,
могут не работатьuseLayoutEffect на сервере приводит к
предупреждениямХарактерный паттерн для Fresh:
Такой подход позволяет использовать богатую экосистему React, сохраняя ключевые преимущества Fresh: скорость, простоту и строгую серверную ориентацию.