Вибір стеку GUI для JavaScript на основі того, що насправді завантажують ваші користувачі
Дізнайтеся, чому оболонки десктопних систем та бібліотеки компонентів є окремими шарами, та як обирати Electron, Tauri, MUI, shadcn/ui та інші за розміром завантажуваних файлів.
Пошук „JavaScript GUI toolkit“ зазвичай призводить до списків, де Electron розміщують поруч із Material UI, ніби вони є конкурентами. Це не так: один з них забезпечує вікно, яке можна встановити, а інший — кнопки для розміщення всередині нього, причому більшості реальних продуктів потрібні обидва елементи. У цьому посібнику ці два рівні розглядаються окремо, описуються основні варіанти кожного з них, і до обох застосовується одне вирішальне питання: скільки коду опиняється на пристроях користувачів та скільки з нього насправді було необхідно?
Два рівні, які інші мови об’єднують
У екосистемах на кшталт Qt, GTK чи WinForms інструментарій GUI виконує все одночасно: він відкриває нативне вікно та забезпечує елементи інтерфейсу, які знаходяться всередині нього. JavaScript розділяє цю відповідальність між двома типами інструментів, і саме їх змішування робить більшість порівнянь заплутаними.
- Шелли для робочого столу упаковують веб-код у вигляді програми, яку можна встановити. Вони забезпечують основну структуру програми: нативне вікно, інтеграцію з панеллю завдань, доступ до локальних файлів та інсталятор. Віджети не є частиною цього рішення.
- Бібліотеки компонентів забезпечують інтерактивні елементи, такі як кнопки, таблиці, вибірник дат та діалогові вікна. Вони працюють у браузері та не залежать від того, чи є цей браузер вбудованим у додаток для робочого столу, чи це звичайна вкладка.
Продукт для робочого столу може поєднувати Tauri з MUI; веб-продукт може використовувати лише MUI. Вибір шелла та вибір бібліотеки компонентів — це два окремі рішення.
Питання, яке насправді відрізняє варіанти
У деяких екосистемах ліцензування є вирішальним фактором, адже неправильна умова може змусити вас зробити свій продукт відкритим кодом. У світі JavaScript GUI майже все ліцензується за моделлю MIT, тому ліцензія рідко обмежує можливості. Те, що справді обмежує, — це розмір. Для шеллів різниця полягає між інсталятором розміром кілька мегабайт та інсталятором розміром кілька сотень мегабайт. Для бібліотек компонентів різниця — між надсиланням цілої системи дизайну та надсиланням лише кількох компонентів, які ви дійсно використовуєте. Пам’ятайте про це питання протягом усього наведеного нижче тексту.
Номери версій, наведені тут, відображають стан npm на момент написання тексту; перевірте реєстр перед тим, як покладатися на них. Щоб детальніше дізнатися про версії для настільних ПК, включаючи новіші середовища виконання, перегляньте наше порівняння варіантів Electron, Tauri, Electrobun та Deno для настільних ПК.
Шелли для настільних ПК
Electron: перевірений стандарт із вбудованим браузером
Electron (версія 44.3.0 на момент написання, ліцензія MIT) додається як залежність для розробки:
npm install --save-dev electron
Він об’єднує повний браузер Chromium разом із середовищем виконання Node.js з вашим додатком. Інтерфейс — це веб-сторінка, а серверна частина — Node. Найсильнішою перевагою є його зрілість: VS Code, Slack, Discord, Figma та 1Password всі побудовані на ньому, а для пакетування, автоматичних оновлень, підпису коду та звітування про збої існують добре задокументовані інструменти, які вже знайомі багатьом командам.
Другою перевагою є однакове відображення. Оскільки браузер постачається разом із додатком, він виглядає однаково на Windows, macOS та Linux, і ви тестуєте його на одній версії Chromium, а не на трьох різних веб-вью системи. Крім того, це повністю JavaScript-рішення, тож будь-який розробник фронтенду може працювати над основним процесом.
Недолік полягає у тому, що кожен додаток містить браузер. Розмір пакетів зазвичай становить від 80 до 200 МБ, і оскільки кожен додаток Electron запускає окремий Chromium, споживання оперативної пам’яті швидко зростає у користувача, який використовує кілька таких додатків. Ви також несете відповідальність за оновлення цього вбудованого Chromium відповідно до вашого власного графіка випуску.
Tauri: системний webview плюс бекенд на Rust
Tauri (версія 2.11.4 на момент написання, ліцензований за двома правилами Apache-2.0 або MIT) має власну команду створення:
npm create tauri-app@latest
Замість того, щоб вбудовувати браузер, Tauri використовує webview, який вже надає операційна система, а його бекенд написаний на мові 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 (v0.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 MB; це не те, що потрапляє до користувача, але це свідчить про її обсяг. Завантажуваний пакет залежить від належної роботи механізму tree-shaking, і якщо ви не інвестуєте у створення власних тем, все буде виглядати як 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 (v11.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 застосовує цей компроміс на рівні компонентів: покладатися на повну систему дизайну, якою керують інші, чи отримувати лише необхідні елементи від постачальника та самостійно їх підтримувати. Вирішіть, на якій стороні цього компромісу знаходиться ваш продукт, перш ніж починати порівнювати таблиці функцій — тоді короткий список зазвичай сформується сам.