Wybór stacku interfejsu graficznego w JavaScript na podstawie tego, co faktycznie pobierają twoi użytkownicy
Dowiedz się, dlaczego obudowy pulpitu i biblioteki komponentów stanowią odrębne warstwy, oraz jak wybrać Electron, Tauri, MUI, shadcn/ui i inne w zależności od ich masy.
Szukanie „JavaScript GUI toolkit” zazwyczaj przynosi listy, w których Electron umieszczany jest obok Material UI, jakby były one konkurentami. W rzeczywistości tak nie jest: jeden z nich dostarcza okno, które można zainstalować, a drugi – przyciski do umieszczenia w tym oknie; większość rzeczywistych produktów wymaga jednak jednego i drugiego. Ten przewodnik oddziela te dwa poziomy, omawia główne opcje w każdym z nich i stosuje do obu jedno kluczowe pytanie: ile kodu trafia na komputery użytkowników i ile z niego było rzeczywiście konieczne?
Dwa poziomy, które inne języki łączą w jedno
W ekosystemach takich jak Qt, GTK czy WinForms toolkit GUI robi wszystko naraz: otwiera natywne okno i dostarcza elementy interfejsu znajdujące się w jego wnętrzu. JavaScript dzieli tę odpowiedzialność pomiędzy dwa rodzaje narzędzi, a ich mylne łączenie jest przyczyną zamieszania w większości porównań.
- Shelli desktopowe pakują kod internetowy jako aplikację do zainstalowania. Dostarczają one ramę aplikacji: natywnie wyglądające okno, integrację z paskiem zadań, dostęp do plików lokalnych oraz program instalacyjny. Widgety nie są częścią tego rozwiązania.
- Biblioteki komponentów dostarczają elementy interaktywne, takie jak przyciski, tabele, wybieracze dat i okna dialogowe. Działają one w przeglądarce i nie zależy im na tym, czy ta przeglądarka jest wbudowana w aplikację desktopową, czy to zwykła karta.
Produkt desktopowy może łączyć Tauri z MUI; produkt internetowy może używać samego MUI. Wybór shella i wybór biblioteki komponentów to dwie odrębne decyzje.
Pytanie, które naprawdę rozróżnia opcje
W niektórych ekosystemach licencjonowanie jest decydującym czynnikiem, ponieważ niewłaściwa zobowiązująca umowa może zmusić cię do udostępnienia produktu na licencji otwartej. W świecie interfejsów graficznych w JavaScriptie prawie wszystko jest licencjonowane na zasadach MIT, więc taka licencja rzadko ogranicza możliwości. To, co je ogranicza, to rozmiar pliku. W przypadku shelli różnica polega na rozmiarze instalatora – od kilku megabajtów do kilkuset. W przypadku bibliotek komponentów różnica występuje między dostarczeniem całego systemu projektowego a dostarczeniem tylko tych nielicznych komponentów, których faktycznie używasz. Pamiętaj o tym pytaniu podczas analizy obu części poniżej.
Liczby wersji podane tutaj odnoszą się do npm w momencie pisania tekstu; sprawdź rejestr przed poleganiem na nich. Aby uzyskać bardziej szczegółowe informacje dotyczące środowiska desktopowego, w tym nowszych środowisk wykonywania, zapoznaj się z naszym porównaniem opcji desktopowych Electron, Tauri, Electrobun i Deno.
Shelli desktopowe
Electron: sprawdzona domyślna opcja z wbudowanym przeglądarką
Electron (wersja 44.3.0 w momencie pisania tekstu, licencja MIT) jest dodawany jako zależność rozwojowa:
npm install --save-dev electron
Pakiet ten zawiera kompletny przeglądarkę Chromium wraz z środowiskiem działania Node.js razem z twoją aplikacją. Interfejs użytkownika to strona internetowa, a warstwa backendu to Node. Jego największą zaletą jest dojrzałość: VS Code, Slack, Discord, Figma i 1Password są wszystkie zbudowane na tej bazie, a narzędzia do pakowania, automatycznych aktualizacji, podpisywania kodu oraz raportowania błędów są dobrze udokumentowane i znane wielu zespołom.
Drugą zaletą jest spójne renderowanie. Ponieważ dostarczasz sam przeglądarkę, aplikacja wygląda identycznie na Windows, macOS i Linux, a testy przeprowadzasz na jednej wersji Chromium zamiast na trzech różnych przeglądarkach systemowych. Jest to również rozwiązanie typu JavaScript end to end, więc każdy deweloper frontendu może pracować nad głównym procesem.
Kosztem jest to, że każda aplikacja zawiera przeglądarkę. Pakiety zazwyczaj zajmują od 80 do 200 MB, a ponieważ każda aplikacja Electron uruchamia oddzielną instancję Chromium, zużycie pamięci RAM szybko rośnie u użytkownika uruchamiającego kilka takich aplikacji. Naprawa tego wbudowanego Chromium również jest twoją odpowiedzialnością, zgodnie z twoim własnym harmonogramem wydawania aktualizacji.
Tauri: systemowy webview w połączeniu z backendem w języku Rust
Tauri (wersja 2.11.4 w momencie pisania, licencjonowane pod dwoma warunkami – Apache-2.0 lub MIT) posiada własną komendę do tworzenia aplikacji:
npm create tauri-app@latest
Zamiast pakować własny przeglądarkę, Tauri wykorzystuje webview dostarczany już przez system operacyjny, a jego warstwa backendowa jest napisana w języku Rust zamiast Node. Różnica w rozmiarze jest strukturalna, a nie wynikająca z dodatkowych elementów: według powszechnie podawanych danych pliki Tauri wynoszą około 3 do 10 MB w porównaniu z 120 do 200 MB u Electron, przy czym zużycie pamięci jest o 50 do 75 procent mniejsze, a uruchamianie szybsze. Ponieważ ta różnica wynika z architektury, a nie z optymalizacji, utrzymuje się ona we wszystkich wersjach.
Model bezpieczeństwa również się różni. W Electron JavaScript frontendu może uzyskać dostęp do systemu operacyjnego za pośrednictwem Node, chyba że zablokuje się to specjalnie. W Tauri frontend rozpoczyna pracę bez żadnego dostępu do systemu; operacje uprzywilejowane to funkcje w języku Rust, które frontend wywołuje podanym nazwą. Wersja Tauri 2 wprowadziła system uprawnień, który kontroluje, jakie API mogą wywoływać poszczególne okna. Tauri 2 jest również dostępny na iOS i Android, czego Electron w ogóle nie oferuje, co ma znaczenie dla zespołów chcących mieć jeden kod źródłowy zarówno na komputerach stacjonarnych, jak i w urządzeniach mobilnych.
Wady są rzeczywiste. Każdy własny przeglądarkowy silnik każdej platformy renderuje treści nieco inaczej, więc teraz testujesz trzy silniki zamiast jednego. Wszystko, co wykracza poza interfejs użytkownika, wymaga użycia języka Rust. Na systemie Windows Tauri polega na WebView2, który jest obecny w praktycznie wszystkich nowoczesnych instalacjach, ale czasami wymaga dodatkowego narzędzia bootstrapującego. Rozsądna zasada: jeśli rozmiar pliku nie jest jeszcze powodem skarg klientów, wybieranie Tauri wyłącznie po to, by zaoszczędzić kilka megabajtów, to zbyt wczesna optymalizacja. Zastosuj je wtedy, gdy wymaganiami są kompaktowe instalatory, niewielkie zużycie pamięci, bardziej ścisła izolacja lub wersja przeznaczona do urządzeń mobilnych.
NW.js: starszy narzędzie do pakowania Chromium
NW.js (wersja 0.115.0 w momencie pisania, licencja MIT) instaluje się jako zwykły pakiet:
npm install nw
Zawiera również Chromium i w rzeczywistości powstał przed Electronem. Jego charakterystyczną cechą jest to, że Node i DOM dzielą jeden kontekst, więc strona internetowa może bezpośrednio korzystać z API Node, bez konieczności rozdzielenia procesów głównego i renderującego w Electronie. Dla niektórych aplikacji jest to prostsze do zrozumienia. Wadą jest znacznie mniejsza społeczność: mniej materiałów edukacyjnych, mniej narzędzi do pakowania oraz mniej pomocy w trudnościach, podczas gdy rozmiar plików pozostaje taki sam jak w Electronie.
Neutralino: najmniejszy możliwy opakowujący element
Neutralino (CLI wersja 11.7.2 w momencie pisania, licencja MIT) jest uruchamiany za pomocą globalnie zainstalowanego interfejsu linii poleceń:
npm install -g @neutralinojs/neu
Jest to lekki, natywny plik binarny oparty na systemowym webview, bez użycia Node ani Chromium. Pliki z tym narzędziem mają zazwyczaj rozmiar od 1 do 5 MB, są nawet mniejsze niż w przypadku Tauri, ponieważ angażuje mniej komponentów frameworku. Jeśli potrzebujesz jedynie otoczyć istniejący interfejs internetowy i dodać ikonkę na pasku zadań, proste funkcje przechowywania danych oraz ograniczony dostęp do plików, Neutralino to rozwiązanie wymagające najmniejszej ilości zasobów do wykonania zadania. Posiada najmniejszy ekosystem oraz najwęższy zakres możliwości natywnych spośród tych czterech, dlatego należy je traktować jako framework pomocniczy, a nie platformę do tworzenia złożonych aplikacji.
Biblioteki komponentów
Wszystko w tej kategorii działa w przeglądarce, więc każda opcja sprawdza się równie dobrze zarówno w środowisku desktopowym, jak i w zwykłej karcie. W tym przypadku kwestia rozmiaru przenosi się z wielkości instalatora na ilość kodu biblioteki, którą plik musi ze sobą przenosić.
MUI: maksymalne pokrycie funkcji, domyślnie styl Material
MUI (wersja 9.4.0 w momencie pisania, licencja MIT) jest instalowane razem ze swoim silnikiem stylizacji Emotion:
npm install @mui/material @emotion/react @emotion/styled
Wśród bibliotek komponentów React jest to największa i najdłużej istniejąca, a jej projekt opiera się na systemie Material Design firmy Google. Zawiera ogromną liczbę komponentów, doskonałą dokumentację, a jej siatka danych radzi sobie z dużymi ilościami informacji. Jeśli potrzebujesz jakiegoś komponentu, MUI prawie na pewno go posiada, a ktoś inny już zadał o niego to samo pytanie.
Jest to jednak również dość duża biblioteka. Nowa instalacja zajmuje około 19 MB w katalogu node_modules; to nie jest ilość, która trafia do użytkowników, ale wskazuje na jej rozmiar. Gotowy plik aplikacji zależy od prawidłowego działania mechanizmu tree-shaking, a jeśli nie zainwestujesz w tworzenie własnych tematów, wszystko będzie wyglądać jak Material Design, co jednym zespołom się podoba, a innym wydaje się ograniczające.
shadcn/ui: kopiuj źródło zamiast dodawać zależność
shadcn/ui (CLI wersja 4.21.0 w momencie pisania, licencja MIT) to nie pakiet, który importujesz. Jego interfejs wiersza poleceń inicjuje projekt, a następnie kopiuje do niego poszczególne komponenty:
npx shadcn@latest init
npx shadcn@latest add button dialog
Każdy komponent łączy elementy bazowe Radix UI z stylizacją Tailwind, a po uruchomieniu interfejsu wiersza poleceń pozostaje to zwykły kod źródłowy przechowywany w twoim repozytorium. Jeśli przycisk wymaga innego zachowania, edytujesz sam przycisk; nie ma żadnego komponentu otaczającego, żadnej API do modyfikacji tematyki ani osoby odpowiedzialnej, którą trzeba przekonać. Ponadto zapewnia on uczciwość pliku budowlanego: dodaj cztery komponenty i tylko one trafią do końcowej wersji aplikacji.
Cena posiadania to konieczność utrzymania. Żadne npm update nie poprawi twoich komponentów; aktualizacja oznacza ręczne skopiowanie i dostosowanie zmian. Ponadto zakłada użycie Tailwind, co sprawia, że nie nadaje się do projektów, które go nie wykorzystują. Ten model funkcjonuje, ponieważ odwraca typową walkę pomiędzy wygodą a możliwościami personalizacji: otrzymujesz solidny punkt wyjścia i pełną kontrolę, a w zamian aktualizacje stają się twoim problemem.
Ant Design: stworzony dla zintegrowanych interfejsów korporacyjnych
Ant Design (wersja 6.6.3 w momencie pisania, licencja MIT) pochodzi od Alibaba i instaluje się jako pojedynczy pakiet:
npm install antd
Oferuje najpełniejszy zestaw komponentów dla interfejsów biznesowych wymagających dużej ilości danych: zaawansowane tabele, złożone formularze, listy transferowe, wybory drzewiaste. Dla konsol administracyjnych i narzędzi wewnętrznych widget, którego potrzebujesz, prawdopodobnie już istnieje. Jest to również najcięższa biblioteka na tej liście – po zainstalowaniu zajmuje około 61 MB na dysku, co stanowi mniej więcej trzy razy tyle co MUI – a jej silna tożsamość wizualna sprawia, że trudniej jest od niej odstąpić niż w przypadku Material.
Mantine: dobre domyślne ustawienia bez nadmiernych upodobań
Mantine (wersja 9.6.1 w momencie pisania, licencja MIT) oddziela swoje podstawowe komponenty od pakietu hooks:
npm install @mantine/core @mantine/hooks
Zespoły, które uważają MUI za zbyt narzucające własne rozwiązania, a shadcn/ui za zbyt inwazyjne pod względem kontroli, często trafiają tutaj. Oferuje on duży zestaw komponentów, rozsądne domyślne ustawienia, proste tematyzowanie, silne wsparcie dla TypeScript oraz solidne wsparcie dla trybu ciemnego bez dodatkowej konfiguracji. Nawet osobno pakiet hooks, zawierający narzędzia do wykrywania kliknięć poza obszarem komponentu, przechowywania lokalnego i zapytań mediów, jest przydatny sam w sobie. Jego społeczność jest mniejsza niż w przypadku MUI czy Ant Design, więc można się spodziewać mniej rozszerzeń od stron trzecich oraz mniej gotowych rozwiązań.
Radix UI i Headless UI: funkcjonalność bez stylizacji
Radix UI (wersja 1.1.23 w momencie pisania) oraz Headless UI (wersja 2.2.10), oba licencjonowane na zasadach MIT, są instalowane indywidualnie dla poszczególnych elementów lub jako jeden pakiet:
npm install @radix-ui/react-dialog
npm install @headlessui/react
To są elementy surowe bez stylizacji. Zajmują się one zachowaniem, nawigacją klawiaturą, zarządzaniem fokusem i dostępnością, pozostawiając wszystkie decyzje wizualne tobie. Taki podział jest cenny, ponieważ tworzenie elementów dostępnych wymaga więcej pracy, niż się wydaje. Odpowiednia rozmowa musi utrzymywać fokus wewnątrz siebie podczas otwarcia, przywracać go po zamknięciu, zamykać się przy naciśnięciu klawisza Escape oraz być prawidłowo informowana przez technologie wspomagające; odpowiedni menu rozwijane wymaga nawigacji klawiszami strzałek, możliwości wyboru poprzez wpisywanie tekstu oraz rozsądnego umieszczenia blisko krawędzi obszaru widoku. Większość zespołów nie docenia tej pracy i wypuszcza produkty z subtelnymi błędami.
Radix stanowi podstawę, na której buduje się shadcn/ui, natomiast Headless UI jest utrzymywany przez zespół Tailwind. Oczywistą konsekwencją jest to, że musisz sam napisać całą stylizację, co stanowi istotę tego podejścia, ale nadal wymaga realnej pracy.
PrimeReact: szeroka gama dla nietypowych komponentów
PrimeReact (wersja 11.1.0 w momencie pisania) należy do rodziny PrimeFaces, która obejmuje również Angular, Vue i Java:
npm install primereact
Oferuje on ogromny zakres funkcji – od wykresów i diagramów organizacyjnych po tabele drzewiaste, planery zadań, elementy do przesyłania plików oraz kompletny zestaw pol wprowadzania danych, z których wiele innych bibliotek w ogóle nie zawiera. Gdy potrzebujesz czegoś nietypowego, warto najpierw sprawdzić to tutaj.
Zanim zastosujesz tę bibliotekę, sprawdź sam warunki licencji. Jej metadane w npm wskazują na plik licencyjny ("SEE LICENSE IN LICENSE.md") zamiast identyfikatora SPDX, a dostawca oferuje również płatne tematy i szablony oprócz wersji darmowej. Biblioteka podstawowa jest otwarta kodowo, ale przeczytaj dokładne warunki przed tworzeniem na jej bazie produktu komercyjnego.
Kolejne trzy biblioteki wartych uwagi
- Chakra UI (v3.37.0, MIT) stawia na dostępność i formatuje komponenty za pomocą propów; znajduje się gdzieś pomiędzy kompleksowym podejściem MUI a prostymi elementami Radix.
- daisyUI (v5.7.34, MIT) to plugin do Tailwind, który dostarcza klasy komponentów zamiast komponentów React, co oznacza, że można go używać również w Svelte, Vue lub statycznym markupu.
- HeroUI (v3.2.4, MIT), przemianowany następca NextUI, łączy Tailwind z React Aria.
Krótki przewodnik decyzyjny
Dla środowiska desktopowego:
- Zaufany ekosystem, identyczne renderowanie wszędzie oraz zespół pracujący wyłącznie w JavaScriptie wskazują na Electron.
- Mniejsze rozmiary plików do pobrania, niska zużycie pamięci, bardziej rygorystyczny model bezpieczeństwa lub celowanie w urządzenia mobilne wskazują na Tauri.
Jeśli chodzi o biblioteki komponentów:
- Potrzeba niemal wszystkich komponentów wraz z doskonałą dokumentacją wskazuje na MUI.
- Pożądanie pełnej kontroli nad kodem w projekcie Tailwind prowadzi do shadcn/ui.
- Gęste ekranowe interfejsy korporacyjne wskazują na Ant Design.
- Dobre domyślne ustawienia bez silnych preferencji wskazują na Mantine.
- Spersonalizowany system projektowy z załatwioną dostępnością wskazuje na Radix lub Headless UI.
- Niezwykły, specjalistyczny komponent wskazuje na PrimeReact.
Jedna zasada przeważa nad całym списком: jeśli wasz zespół już dobrze zna jeden z tych narzędzi, ta wiedza prawie zawsze przeważa nad nieco lepszym rozwiązaniem gdzie indziej.
Zakończenie
W obu warstwach listy funkcji w dużej mierze się zbiegają; projekty te miały lata na kopiowanie dobrych pomysłów od siebie nawzajem. Różnice w rozmiarze plików wciąż są widoczne dla użytkowników. Wybór między Electron a Tauri dotyczy właśnie tego aspektu dla całej aplikacji: czy zapakować przeglądarkę, aby uzyskać przewidywalność, czy skorzystać z tej dostarczanej przez system operacyjny, co pozwala na plik o rozmiarze dwudziestokrotnie mniejszym lub większym. Wybór między MUI a shadcn/ui odnosi się do warstwy komponentów: czy polegać na kompletnym systemie projektowym utrzymywanym przez innych, czy kupować tylko te elementy, których potrzebuje się, i samodzielnie je utrzymywać. Zdecyduj, po której stronie tej równowagi znajduje się twój produkt, zanim zaczniesz porównywać tabele funkcji – wtedy lista kandydatów zazwyczaj sama się wybierze.
Literatura pokrewna
- Poza rozmiarem pakietu: odkrywanie tego, co naprawdę spowalnia twoją aplikację webową — Dlaczego redukcja liczby kilobajtów rzadko naprawia wolną aplikację oraz jak śledzić rzeczywisty czas oczekiwania na serwerach, w procesach typu waterfall, przy wykorzystaniu mechanizmów hydration, skryptów i obrazów od stron trzecich.
- Porównanie frameworki desktopowych JavaScript: Electron, Tauri, Electrobun, Deno — Porównanie frameworków Electron, Tauri, Electrobun i Deno pod kątem wydajności, rozmiaru i bezpieczeństwa, aby pomóc ci wybrać odpowiedni framework desktopowy w 2026 roku.