Выбор стека GUI на JavaScript в зависимости от того, что на самом деле загружают ваши пользователи
Узнайте, почему оболочки рабочего стола и библиотеки компонентов представляют собой отдельные слои, и как выбирать Electron, Tauri, MUI, shadcn/ui и другие в зависимости от размера их пакетов.
Поиск «инструментария GUI для JavaScript» обычно приводит к спискам, в которых Electron ставится рядом с Material UI, как будто они конкуренты. На самом деле это не так: один из них предоставляет установляемое окно, а другой — кнопки для его заполнения, причем большинству реальных продуктов нужны и то, и другое. В этом руководстве эти два компонента рассматриваются отдельно, описываются основные варианты каждого из них, и к обоим применяется один ключевой вопрос: сколько кода окажется на устройствах пользователей и сколько из него действительно было необходимо?
Два слоя, которые в других языках объединены
В экосистемах вроде Qt, GTK или WinForms инструментарий GUI выполняет всё сразу: он открывает нативное окно и предоставляет элементы управления, находящиеся внутри него. JavaScript разделяет эту ответственность между двумя типами инструментов, и именно путаница от смешивания этих инструментов делает большинство сравнений запутанными.
- Оболочки рабочего стола преобразуют веб-код в установляемое приложение. Они предоставляют структуру приложения: нативное окно, возможность интеграции в панель задач, доступ к локальным файлам и установщик. Виджеты не входят в состав таких решений.
- Библиотеки компонентов обеспечивают интерактивные элементы, такие как кнопки, таблицы, выбрасыватели дат и диалоговые окна. Они работают в браузере и не зависят от того, является ли этот браузер частью приложения для рабочего стола или обычной вкладки.
Продукт для рабочего стола может сочетать Tauri с MUI; веб-продукт может использовать только MUI. Выбор оболочки и выбор библиотеки компонентов — это два отдельных решения.
Вопрос, который действительно разделяет варианты
В некоторых экосистемах лицензирование является решающим фактором, поскольку неподходящие условия могут вынудить вас сделать свой продукт открытым исходным кодом. В мире JavaScript-интерфейсов практически всё распространяется под лицензией MIT, поэтому лицензия редко ограничивает возможности. Однако ограничения могут быть связаны с размером. Для оболочек разница заключается между установщиком в несколько мегабайт и установщиком размером в несколько сотен мегабайт. Для библиотек компонентов разница — между поставкой всей системы дизайна и поставкой лишь тех немногих компонентов, которые действительно используются. Имейте этот вопрос в виду при рассмотрении обоих аспектов ниже.
Указанные здесь номера версий отражают состояние npm на момент написания текста; перед тем как полагаться на них, проверьте реестр. Чтобы узнать больше о десктопных решениях в частности, включая более новые среды выполнения, ознакомьтесь с нашим сравнением десктопных вариантов Electron, Tauri, Electrobun и Deno.
Десктопные оболочки
Electron: проверенный стандарт с встроенным браузером
Electron (версия 44.3.0 на момент написания, лицензия MIT) добавляется как зависимость для разработки:
npm install --save-dev electron
Этот инструмент объединяет полноценный браузер Chromium вместе с средой выполнения Node.js с вашим приложением. Интерфейс представляет собой веб-страницу, а серверная часть — Node.js. Самым сильным преимуществом является зрелость этой технологии: VS Code, Slack, Discord, Figma и 1Password все построены на ней, к тому же существуют хорошо задокументированные инструменты для пакетации, автоматических обновлений, подписи кода и отчетов о сбоях, которые уже знакомы многим командам.
Вторым преимуществом является единообразие отображения. Поскольку браузер поставляется вместе с приложением, оно выглядит одинаково на Windows, macOS и Linux, причем тестирование проводится с использованием одной версии Chromium, а не трех разных веб-вью системы. Кроме того, это полностью JavaScript-решение, поэтому любой разработчик фронтенда может работать над основным процессом.
Подобный подход имеет свою цену — каждое приложение включает в себя браузер. Размер таких пакетов обычно составляет от 80 до 200 МБ, и поскольку каждое приложение Electron запускает отдельную копию Chromium, потребление оперативной памяти быстро растет у пользователя, запускающего несколько таких приложений. Обновление этого встроенного Chromium также является вашей ответственностью в соответствии с вашим собственным графиком выпусков.
Tauri: системный веб-вью с фоновым ядром на Rust
Tauri (версия 2.11.4 на момент написания, лицензирован по двойной лицензии Apache-2.0 или MIT) предоставляет собственную команду для создания проектов:
npm create tauri-app@latest
Вместо встраивания браузера Tauri использует веб-вью, уже предоставляемый операционной системой, причем его бэкенд написан на Rust вместо Node. Разница в размере обусловлена структурой решения, а не дополнительными элементами: по обычно приводимым данным размер пакетов Tauri составляет примерно 3–10 МБ по сравнению с 120–200 МБ у Electron, при этом потребление памяти на 50–75 процентов меньше, а запуск происходит быстрее. Поскольку эта разница связана с архитектурой, а не с настройками, она сохраняется во всех версиях.
Модель безопасности также отличается. В Electron JavaScript фронтенда может получить доступ к операционной системе через Node, если только его не ограничить. В Tauri фронтенд начинает работу без доступа к системе; привилегированные операции выполняются с помощью функций на языке Rust, которые фронтенд вызывает по имени. В Tauri v2 была введена система прав, контролирующая, какие API может использовать каждое окно. Tauri 2 также поддерживает iOS и Android, чего совершенно не делает Electron, что важно для команд, желающих иметь единый кодовый базис как для настольных, так и для мобильных устройств.
Недостатки действительно существуют. Веб-вью каждой платформы отображает контент немного по-разному, поэтому теперь приходится тестировать три движка вместо одного. Для чего-либо, что выходит за рамки фронтенда, требуется использование Rust. В Windows Tauri опирается на WebView2, который присутствует практически во всех современных установках, но иногда требует специального загрузчика. Разумное правило: если размер пакета ещё не стал причиной жалоб клиентов, выбор Tauri исключительно ради сокращения количества мегабайт — это преждевременная оптимизация. Обратитесь к нему тогда, когда компактные установщики, небольшое потребление памяти, более строгая изоляция или создание версии для мобильных устройств являются реальными требованиями.
NW.js: старый инструмент для сборки Chromium
NW.js (версия 0.115.0 на момент написания, лицензия MIT) устанавливается как обычный пакет:
npm install nw
Он также включает Chromium и по сути предшествует Electron. Его отличительная особенность заключается в том, что Node и DOM делят один контекст, поэтому веб-страница может напрямую вызывать API Node, без разделения процессов main и renderer в Electron. Для некоторых приложений это упрощает понимание логики работы. Однако цена этого — гораздо меньшее сообщество: меньше учебных материалов, меньше инструментов для пакетирования и меньше помощи в случае проблем, при этом размер бандлов остается таким же, как у Electron.
Neutralino: самый маленький возможный оберток
Neutralino (CLI версии 11.7.2 на момент написания, лицензия MIT) использует глобально установленный CLI:
npm install -g @neutralinojs/neu
Это легкий нативный бинарник, работающий вокруг системного веб-просмотрщика, без использования Node или Chromium. Размер пакетов обычно составляет от 1 до 5 МБ, что даже меньше, чем у Tauri, поскольку здесь задействовано меньше фреймворков. Если вам нужно лишь обернуть существующий веб-интерфейс и добавить значок на панель задач, а также реализовать простую функцию сохранения данных и ограниченный доступ к файлам, то Neutralino — это наименее сложное решение для выполнения этих задач. У него самая маленькая экосистема и самый узкий набор нативных возможностей среди четырех вариантов, поэтому его следует рассматривать как утилитарный фреймворк, а не как платформу для сложных приложений.
Библиотеки компонентов
Все, что находится в этой категории, работает в браузере, поэтому каждый из вариантов одинаково хорошо функционирует как внутри десктопной оболочки, так и в обычном вкладке. Здесь вопрос размера смещается с размера установочного файла на объем кода библиотек, который тянется вместе с пакетом.
MUI: максимальная функциональность, по умолчанию стиль Material
MUI (версия 9.4.0 на момент написания, лицензия MIT) устанавливается вместе со своим движком стилизации Emotion:
npm install @mui/material @emotion/react @emotion/styled
Среди библиотек компонентов React это самая крупная и давно существующая, она следует системе Material Design от Google. Ассортимент компонентов огромен, документация отличная, а функция таблицы данных позволяет обрабатывать большие объемы информации. Если вам нужен какой-либо компонент, скорее всего, он есть в MUI, и кто-то уже задавал по нему вопросы.
Это также довольно объемная библиотека. Размер новой установки в папке node_modules составляет около 19 МБ; это не то, что доходит до пользователей, но это показывает ее масштаб. Готовый пакет, который вы отправляете пользователям, зависит от корректной работы механизма сокращения размера кода, и если вы не внедрите собственные темы, все будет выглядеть в стиле Material Design, что некоторым командам нравится, а другим кажется слишком ограничивающим.
shadcn/ui: копируйте исходный код вместо добавления зависимости
shadcn/ui (CLI версии 4.21.0 на момент написания, лицензия MIT) — это не пакет, который нужно импортировать. Его CLI инициализирует проект, а затем копирует отдельные компоненты в него:
npx shadcn@latest init
npx shadcn@latest add button dialog
Каждый компонент сочетает примитивы Radix UI с стилизацией Tailwind, и после запуска CLI это просто исходный код, находящийся в вашем репозитории. Если кнопке нужно другое поведение, вы редактируете саму кнопку; нет никаких оберточных компонентов, никакого API для настройки тем и никого, кого нужно убеждать. Это также делает бандл прозрачным: добавьте четыре компонента, и только они попадут в результат сборки.
Стоимость владения — это обслуживание. Никакой npm update не улучшит ваши компоненты; обновление означает ручную копию и синхронизацию изменений. К тому же он предполагает использование Tailwind, из-за чего плохо подходит для проектов, которые им не пользуются. Эта модель работает благодаря тому, что меняет обычный баланс между удобством и настройкой: вы получаете надёжную отправную точку и полный контроль, а взамен обновления становятся вашей проблемой.
Ant Design: создано для насыщенных корпоративных интерфейсов
Ant Design (версия 6.6.3 на момент написания, лицензия MIT) происходит от Alibaba и устанавливается как единый пакет:
npm install antd
Он предлагает самый полный набор компонентов для бизнес-интерфейсов с большим объемом данных: продвинутые таблицы, сложные формы, списки передачи данных, деревья выбора. Для админ-панелей и внутренних инструментов необходимый вам виджет, скорее всего, уже существует. Это также самая тяжелая библиотека в этом списке — около 61 МБ на диске после установки, примерно в три раза больше, чем MUI; к тому же её выраженная визуальная идентичность заметно сложнее изменить по сравнению с Material.
Mantine: хорошие стандартные настройки без излишних ограничений
Mantine (версия 9.6.1 на момент написания, лицензия MIT) разделяет свои основные компоненты на отдельный пакет hooks:
npm install @mantine/core @mantine/hooks
Команды, считающие MUI слишком директивным, а shadcn/ui слишком интенсивно управляющим деталями, часто выбирают именно его. У него большой набор компонентов, разумные значения по умолчанию, простая система тем, мощная поддержка TypeScript и отличная поддержка режима темноты без дополнительной настройки. Даже отдельно пакет hooks с инструментами для обнаружения кликов вне элемента, работы с локальным хранилищем и медиаквериями полезен сам по себе. Его сообщество меньше, чем у MUI или Ant Design, поэтому ожидайте меньше сторонних расширений и готовых решений.
Radix UI и Headless UI: поведение без стилизации
Radix UI (v1.1.23 на момент написания) и Headless UI (v2.2.10), оба распространяются по лицензии MIT, устанавливаются отдельно для каждого примитива или как единый пакет соответственно:
npm install @radix-ui/react-dialog
npm install @headlessui/react
Это примитивы без стилей. Они обеспечивают поведение, навигацию с помощью клавиатуры, управление фокусом и доступность, оставляя все визуальные решения на ваше усмотрение. Такое разделение важно, поскольку создание доступных виджетов оказывается сложнее, чем кажется. Правильный диалог должен сохранять фокус внутри себя во время открытия, возвращать его при закрытии, закрываться при нажатии клавиши Escape и правильно отображаться средствами вспомогательных технологий; правильный выпадающий список требует навигации с помощью стрелочных клавиш, возможности выбора путем ввода текста и разумного расположения близко к краям области отображения. Большинство команд недооценивают объем работы и выпускают продукт с скрытыми ошибками.
Radix — это основа, на которой строится shadcn/ui, а Headless UI поддерживается командой Tailwind. Очевидная цена заключается в том, что вы сами должны писать всю стилизацию, что и является сутью подхода, но это всё равно требует значительных усилий.
PrimeReact: широкий спектр возможностей для нестандартных компонентов
PrimeReact (версия 11.1.0 на момент написания) относится к семейству PrimeFaces, которое также включает Angular, Vue и Java:
npm install primereact
Эта библиотека предлагает огромный спектр инструментов — от диаграмм и организационных схем до таблиц в виде деревьев, планировщиков, компонентов для загрузки файлов и полного набора элементов ввода, многие из которых совершенно отсутствуют в других библиотеках. Если вам нужно что-то необычное, стоит сначала проверить её здесь.
Перед использованием обязательно убедитесь в условиях лицензирования. Метаданные в npm указывают на файл с лицензией (“SEE LICENSE IN LICENSE.md”) вместо спецификатора SPDX, к тому же разработчик предлагает платные темы и шаблоны наряду с бесплатной версией. Основная библиотека является с открытым исходным кодом, но прочитайте фактические условия перед тем, как создавать на её основе коммерческий продукт.
Ещё три библиотеки, которые стоит рассмотреть
- Chakra UI (v3.37.0, MIT) ставит доступность на первое место и форматирует компоненты с помощью параметров; он находится где-то между комплексным подходом MUI и примитивами Radix.
- daisyUI (v5.7.34, MIT) — это плагин для Tailwind, который предоставляет классы компонентов вместо самих компонентов React, что позволяет использовать его также в Svelte, Vue или статическом маркипаде.
- HeroUI (v3.2.4, MIT), переименованный преемник NextUI, сочетает в себе Tailwind и React Aria.
Краткое руководство по принятию решений
Для настольных приложений:
- Зрелая экосистема, идентичное отображение везде и команда, работающая исключительно с JavaScript, указывают на Electron.
- Малый размер загрузки, низкое потребление памяти, более строгая модель безопасности или целевое использование в мобильных устройствах указывают на Tauri.
Что касается библиотек компонентов:
- Потребность в практически всех компонентах плюс отличная документация указывает на MUI.
- Желание полностью контролировать и изменять код в проекте Tailwind указывает на shadcn/ui.
- Интенсивные корпоративные интерфейсы для работы с данными указывают на Ant Design.
- Хорошие стандартные настройки без излишних ограничений указывают на Mantine.
- Персонализированная система дизайна с учетом доступности указывает на Radix или Headless UI.
- Необычный, специализированный компонент указывает на PrimeReact.
Есть одно правило, которое перевешивает всё остальное: если ваша команда уже хорошо знает один из этих инструментов, такой опыт почти всегда имеет большее значение, чем незначительно лучшая подходящая альтернатива.
Заключение
В обоих подходах списки функций в значительной степени совпали; у этих проектов было много времени, чтобы перенять лучшие идеи у конкурентов. Различия остаются в весе приложения, что ощущается пользователями. Вопрос о весе стоит и для Electron, и для Tauri: использовать браузер в составе приложения для гарантии предсказуемости или опираться на тот, который предоставляет операционная система, что позволяет сделать приложение в двадцать и более раз меньше. Выбор между MUI и shadcn/ui сводится к аналогичному компромиссу на уровне компонентов: полагаться на полную систему дизайна, поддерживаемую другими, или брать только необходимые элементы у поставщика и самостоятельно заниматься их поддержкой. Решите, на чьей стороне этого компромисса будет ваш продукт, прежде чем начинать сравнивать списки функций — тогда оптимальный вариант обычно выберется сам.