Magic UI — animowane komponenty dla Reacta i Tailwinda
Rejestr 75 animowanych komponentów Reacta na licencji MIT, instalowanych narzędziem shadcn wprost do repozytorium — 36 z nich nie ciągnie żadnej zależności npm. Pokazujemy pełne wdrożenie w Laravelu z Inertią zamiast w Next.js: components.json, alias do własnej funkcji cn, dyrektywy „use client” w Rollupie i renderowanie po stronie serwera. Plus rachunek za dostępność: tylko cztery komponenty z siedemdziesięciu ośmiu respektują prefers-reduced-motion.
Landing page ma wyglądać drogo. Nagłówek, który składa się litera po literze, logotypy klientów przewijające się w pętli, delikatna smuga światła obiegająca ramkę karty z cenami, licznik wbijający się w okrągłą liczbę, kiedy sekcja wjeżdża w kadr. Klient tego nie nazwie, ale zobaczy różnicę między stroną, która wygląda jak produkt, a stroną, która wygląda jak dokumentacja.
Problem w tym, że zespół backendowy nie ma animatora, a każdy z tych efektów to pół dnia dłubania w requestAnimationFrame, masce CSS albo w API IntersectionObservera — plus drugie pół dnia na to, żeby nie zamulało telefonu i nie wywracało hydracji przy renderowaniu po stronie serwera.
Magic UI (github.com/magicuidesign/magicui, licencja MIT) jest zbiorem takich efektów, gotowych do wklejenia. Nie jest biblioteką w rozumieniu paczki npm i to jest w nim najciekawsze: kod komponentu ląduje w twoim repozytorium jako zwykły plik, który możesz przeczytać, zmienić i skasować. Poniżej to, co realnie dostajesz, gdzie są koszty, i jak to wpiąć w projekt Laravela z Inertią zamiast w Next.js, na który projekt jest domyślnie nastawiony.
Czym to jest, a czym nie jest
Magic UI opisuje się jako „UI Library for Design Engineers”. Praktyczniej: to warstwa marketingowa nad shadcn/ui. shadcn/ui daje komponenty, z których buduje się aplikację — przyciski, formularze, dialogi, tabele. Magic UI daje to, czym się tę aplikację sprzedaje — nagłówki, tła, mockupy urządzeń, efekty przewijania.
Podział jest czysty i to nie przypadek: oba projekty używają tej samej konfiguracji Tailwinda, tych samych zmiennych CSS i tego samego narzędzia wiersza poleceń. Magic UI świadomie nie dubluje niczego z shadcn/ui.
Stan repozytorium na dziś, prosto z API GitHuba i z pliku registry.json:
- 22 147 gwiazdek, 1 116 forków, 152 kontrybutorów, repozytorium założone 26 czerwca 2023,
- ostatni commit 11 sierpnia 2026 — poprawka do
animated-theme-toggler, chroniąca przed zawieszeniem kompozytora przeglądarki przy szybkim klikaniu, - dwa otwarte zgłoszenia, oba to pull requesty z nowymi komponentami (tło z falami wody na WebGL i cząsteczki 3D na canvasie). Zero otwartych błędów,
- 75 komponentów typu
registry:uiw rejestrze plus 133 gotowe przykłady użycia, - razem 12 096 linii TSX w katalogu
registry/magicui— całość, wszystkie warianty, komplet.
Ta ostatnia liczba jest ważniejsza, niż wygląda. Cała biblioteka mieści się w dwunastu tysiącach linii, a ty i tak kopiujesz do siebie tylko te pliki, których używasz. Marquee to 74 linie. Border beam — 107. To jest kod, który da się przeczytać w przerwie na kawę i poprawić, kiedy przestanie pasować, zamiast zgłaszać błąd i czekać na wydanie.
Skąd rozbieżność w liczbie komponentów
W opisach Magic UI regularnie pojawia się „150+ komponentów”. W rejestrze jest ich 75, w katalogu źródłowym 78 plików .tsx (kilka najnowszych nie trafiło jeszcze do rejestru). Reszta to przykłady — 133 wpisy typu registry:example, czyli warianty w rodzaju „marquee poziomy”, „marquee pionowy”, „marquee 3D”, „marquee z logotypami”. Każdy z nich da się zainstalować osobno i każdy jest osobnym punktem na stronie z dokumentacją, ale komponentów jako takich jest 75.
Nie jest to naciąganie na tyle poważne, żeby projekt przez to skreślać — po prostu przy planowaniu warto liczyć 75, nie 150.
Instalacja: rejestr shadcn zamiast paczki npm
Magic UI nie ma pakietu w npm. Instalacja komponentu to pobranie jego pliku JSON z rejestru i zapisanie kodu w twoim projekcie. Robi to narzędzie shadcn (wersja 4.20.1 z 2 września 2026):
npx shadcn@latest add @magicui/marqueePrefiks @magicui to przestrzeń nazw rejestru. Narzędzie rozwija ją do adresu https://magicui.design/r/{name}.json, pobiera plik, zapisuje komponent w katalogu skonfigurowanym jako ui, dokłada brakujące zależności npm i dopisuje potrzebne zmienne CSS.
Przestrzeni @magicui nie musisz nigdzie deklarować. Jest w centralnym indeksie rejestrów open source, który shadcn utrzymuje pod adresem ui.shadcn.com/r/registries.json — na dziś 292 pozycje, a Magic UI ma tam ocenę zdrowia 97,3 na 100 (dostępność, poprawność schematów, instalowalność). Jeśli jednak wolisz przypiąć adres na sztywno albo trzymasz własny rejestr firmowy, blok wygląda tak:
{
"registries": {
"@magicui": "https://magicui.design/r/{name}.json",
"@firmowy": {
"url": "https://design.firma.pl/r/{name}.json",
"headers": { "Authorization": "Bearer ${REGISTRY_TOKEN}" }
}
}
}Tryb ręczny też jest przewidziany: dokumentacja każdego komponentu ma zakładkę „Manual” z pełnym źródłem do skopiowania i listą animacji CSS do dopisania. Przy audycie bezpieczeństwa, który zabrania narzędziom CLI pisać po repozytorium, to jest realna ścieżka, a nie kurtuazja.
Co jest w katalogu
Siedemdziesiąt pięć komponentów układa się w kilka rodzin. Warto je znać z nazwy, bo szukanie po funkcji na stronie z dokumentacją jest wolniejsze niż wpisanie nazwy w wiersz poleceń.
Tekst
text-animate (najbardziej rozbudowany — cztery tryby podziału: całość, słowa, znaki, linie, i dziesięć wariantów wejścia), typing-animation, hyper-text, morphing-text, word-rotate, flip-text, box-reveal, text-reveal, sparkles-text, aurora-text, line-shadow-text, animated-gradient-text, animated-shiny-text, spinning-text, comic-text, video-text (tekst jako maska na odtwarzanym wideo), highlighter (podkreślenia rysowane odręcznie, na bibliotece rough-notation).
Tła i wzory
particles, meteors, retro-grid, grid-pattern, dot-pattern, flickering-grid, animated-grid-pattern, interactive-grid-pattern, striped-pattern, ripple, warp-background, grid-beams, progressive-blur.
Przyciski i mikrointerakcje
shimmer-button, rainbow-button, pulsating-button, ripple-button, interactive-hover-button, animated-subscribe-button, script-copy-btn, confetti, cool-mode, smooth-cursor, pointer, lens (lupa nad obrazem), scratch-to-reveal.
Układ i struktura
bento-grid, marquee, dock (pasek w stylu macOS), file-tree, terminal (udawana konsola z animowanym wypisywaniem), code-comparison (dwa fragmenty kodu obok siebie, podświetlane przez Shiki), arc-timeline, animated-list, orbiting-circles, animated-beam (linia łącząca dwa elementy DOM, z pulsującym gradientem — kanoniczny „diagram integracji” z każdej strony SaaS-a).
Mockupy urządzeń i efekty specjalne
safari, iphone-15-pro, android, hero-video-dialog, globe (obracająca się kula ziemska na bibliotece cobe, z markerami miast), icon-cloud, glyph-matrix, pixel-image, magic-card, neon-gradient-card, shine-border, border-beam, number-ticker, animated-circular-progress-bar, scroll-progress, scroll-based-velocity, blur-fade, avatar-circles, tweet-card i client-tweet-card, animated-theme-toggler.
Ile to naprawdę kosztuje w zależnościach
Tu Magic UI wypada lepiej, niż sugeruje kategoria „biblioteka animacji”. Rozkład zależności npm w 75 komponentach:
- 36 komponentów nie potrzebuje niczego — czysty React, Tailwind i, gdzie trzeba, canvas. W tej grupie są
marquee,particles,meteors,retro-grid,terminal,safari,iphone-15-pro,shimmer-button,rainbow-button,aurora-text,orbiting-circles,icon-cloud, wszystkie wzory siatek i większość przycisków, - 31 wymaga
motion— czyli biblioteki dawniej znanej jako Framer Motion, - reszta to pojedyncze przypadki:
cobe(globe),canvas-confetti(confetti),rough-notation(highlighter),react-tweet(dwie karty tweetów),shikiplusnext-themes(code-comparisoniscript-copy-btn),@radix-ui/react-icons(bento-grid),lucide-react(przełącznik motywu).
Praktycznie znaczy to tyle, że możesz wziąć z Magic UI pięć efektów i nie zwiększyć rozmiaru paczki JS ani o bajt, o ile trafisz w tę pierwszą grupę. To nie jest typowe dla bibliotek animacji.
Warto też wiedzieć, że w rejestrze siedzi jedna niekonsekwencja: smooth-cursor deklaruje framer-motion, kiedy 31 pozostałych deklaruje motion. Jeśli instalujesz tylko ten jeden komponent, dostaniesz do package.json paczkę pod inną nazwą niż reszta.
motion czy framer-motion — i dlaczego to nie jest to samo pytanie, co rok temu
W npm żyją dziś obie nazwy i obie są w wersji 13.2.0, wydanej tego samego dnia (2 września 2026). Zależności rozstrzygają, co jest czym:
motion@13.2.0zależy odframer-motion@^13.2.0,framer-motion@13.2.0zależy odmotion-domimotion-utils.
Czyli motion to cienka nakładka nad framer-motion, nie osobny silnik. Instalacja obu nie dubluje runtime’u — pod spodem i tak jest jedna kopia motion-dom.
Ale majory muszą się zgadzać. Jeśli projekt ma dziś framer-motion@^12, a ty pozwolisz narzędziu dociągnąć motion@latest, w drzewie wylądują dwie linie 12 i 13 obok siebie: podwójny kod, dwa niezależne zestawy kontekstów Reacta i animacje, które potrafią przestać ze sobą rozmawiać. Dwa wyjścia:
npm install motion@^12 # przypnij major do tego, co masz
# albo, jeśli nie chcesz drugiej nazwy w package.json:
# podmień w pobranych komponentach import "motion/react" na "framer-motion"Druga opcja jest w pełni bezpieczna, bo API w obu nazwach jest identyczne — motion/react reeksportuje to samo. Przy pięciu komponentach to pięć linii do zmiany, a package.json zostaje czysty.
Tailwind v4 jest wymagany
Aktualne Magic UI zakłada Tailwinda w wersji 4. Widać to w samych komponentach — marquee używa składni gap-(--gap) i [--duration:40s], border-beam sięga po mask-intersect i border-(length:--border-beam-width). To są utility klasy z v4, w v3 nie istnieją.
Projekt utrzymuje osobną stronę v3.magicui.design ze starszymi wersjami komponentów dla Tailwinda 3. Nie jest to jednak ścieżka rozwoju — nowe komponenty idą tylko do wersji bieżącej, a oficjalna rada to migracja według przewodnika shadcn/ui.
Druga konsekwencja v4: konfiguracja przeniosła się z tailwind.config.js do CSS. Komponenty, które potrzebują własnych klatek kluczowych, dokładają je do arkusza globalnego. Dla marquee wygląda to tak:
@theme inline {
--animate-marquee: marquee var(--duration) infinite linear;
--animate-marquee-vertical: marquee-vertical var(--duration) linear infinite;
@keyframes marquee {
from { transform: translateX(0); }
to { transform: translateX(calc(-100% - var(--gap))); }
}
@keyframes marquee-vertical {
from { transform: translateY(0); }
to { transform: translateY(calc(-100% - var(--gap))); }
}
}Przy instalacji przez CLI narzędzie dopisuje to samo. Przy trybie ręcznym łatwo o tym zapomnieć — objaw jest wtedy jednoznaczny: treść się renderuje, ale stoi w miejscu.
Wpięcie w Laravela z Inertią
Dokumentacja Magic UI pokazuje wyłącznie Next.js, ale narzędzie shadcn oficjalnie wspiera Laravela z Reactem i Inertią, a komponenty Magic UI nie importują niczego z next/ — sprawdziliśmy cały katalog rejestru, zero takich importów. Jedyne dwa komponenty z zależnością next-themes to code-comparison i script-copy-btn, i tam chodzi o odczyt trybu ciemnego, nie o router.
Nasz stack na tym blogu to Laravel z Inertią 3, React 19, Tailwind 4 i Vite — czyli dokładnie ten przypadek. Poniżej pełna ścieżka.
Krok 1: components.json
Narzędzie shadcn potrzebuje pliku konfiguracyjnego w katalogu głównym projektu. Dla Laravela z Vite i Tailwindem 4:
{
"$schema": "https://ui.shadcn.com/schema.json",
"style": "new-york",
"rsc": false,
"tsx": true,
"tailwind": {
"config": "",
"css": "resources/css/app.css",
"baseColor": "neutral",
"cssVariables": true,
"prefix": ""
},
"aliases": {
"components": "@/components",
"ui": "@/components/ui",
"lib": "@/lib",
"hooks": "@/hooks",
"utils": "@/lib/helpers/cn"
},
"iconLibrary": "lucide"
}Dwie rzeczy warte uwagi. "rsc": false — nie ma serwerowych komponentów Reacta, więc narzędzie nie będzie ich zakładać. "config": "" — w Tailwindzie 4 nie ma pliku konfiguracyjnego, pusty łańcuch jest tu prawidłową wartością.
Najważniejszy jest alias utils. Każdy komponent Magic UI zaczyna się od import { cn } from "@/lib/utils". Jeśli twój projekt trzyma tę funkcję gdzie indziej — u nas to resources/js/lib/helpers/cn.ts — wskaż to tutaj, a narzędzie przepisze import przy zapisie pliku. Bez tego dostaniesz siedemdziesiąt piąte lib/utils.ts w projekcie, który już ma swoje.
Sama funkcja jest zresztą tą samą trzylinijkową sklejką, którą i tak każdy ma:
import clsx, { type ClassValue } from 'clsx'
import { twMerge } from 'tailwind-merge'
export const cn = (...args: ClassValue[]) => twMerge(clsx(args))Krok 2: alias @/ w Vite
Alias musi rozwiązywać się w dwóch miejscach niezależnie: w TypeScripcie (podpowiedzi i sprawdzanie typów) i w Vite (faktyczny bundling). W tsconfig.json:
"paths": { "@/*": ["./resources/js/*"] }W vite.config.js, jeśli jeszcze go tam nie ma:
import path from 'node:path'
export default defineConfig({
// ...
resolve: {
alias: { '@': path.resolve(__dirname, 'resources/js') },
},
})Krok 3: dyrektywy „use client” i ostrzeżenia Rollupa
Pięćdziesiąt siedem z siedemdziesięciu ośmiu komponentów zaczyna się od "use client". Poza Next.js ta dyrektywa nic nie robi — jest zwykłym literałem tekstowym na początku modułu i React ją ignoruje. Kod działa.
Rollup ma jednak zwyczaj ostrzegać przy każdym takim pliku: Module level directives cause errors when bundled, „use client” was ignored. Przy pięciu komponentach to pięć linii szumu w każdym buildzie, przy piętnastu — piętnaście, i po tygodniu nikt już nie czyta wyjścia z npm run build. Wyciszenie jest jednolinijkowe:
build: {
rollupOptions: {
onwarn(warning, warn) {
if (warning.code === 'MODULE_LEVEL_DIRECTIVE') return
warn(warning)
},
},
},Można też po prostu usunąć pierwszą linię z pobranych plików. Wadą jest to, że przy aktualizacji komponentu wróci.
Krok 4: renderowanie po stronie serwera
Tu robi się ciekawie, bo Inertia potrafi renderować po stronie serwera, a osiemnaście komponentów Magic UI sięga po window albo document, a siedem rysuje na canvasie.
Sprawdziliśmy, jak są napisane, i większość zachowuje się poprawnie:
globewołacreateGlobewyłącznie wewnątrzuseEffect, czyli nigdy na serwerze,particlesma jawny wartownik przy odczycie gęstości pikseli:typeof window !== "undefined" ? window.devicePixelRatio : 1, a nasłuchy i pętlę animacji podpina w efekcie.
To nie znaczy, że można przestać patrzeć. Przy każdym komponencie z tej osiemnastki — flickering-grid, glyph-matrix, smooth-cursor, cool-mode, meteors, magic-card, video-text, highlighter i pozostałe — warto rzucić okiem, czy odczyt DOM nie wypadł poza efekt. Plik masz u siebie w repozytorium, więc to jest jedno wyszukanie, nie zgłoszenie błędu do cudzego projektu.
Gdy trafisz na komponent, który się nie broni, ratunek w projekcie z Inertią jest krótki — odłóż go do momentu, w którym drzewo jest już zamontowane w przeglądarce:
import { useEffect, useState } from 'react'
const TylkoWPrzegladarce = ({ children }) => {
const [zamontowane, setZamontowane] = useState(false)
useEffect(() => setZamontowane(true), [])
return zamontowane ? children : null
}Cena jest realna i trzeba ją znać: taki komponent nie istnieje w HTML-u serwowanym przez serwer, więc nie zobaczy go ani crawler, ani czytelnik z wyłączonym JavaScriptem. Do dekoracyjnego tła to nie ma znaczenia. Do nagłówka H1 z animowanym tekstem — ma, i to duże. Nagłówki animuj komponentami, które renderują treść od razu i dopiero ją animują (text-animate, blur-fade), a nie takimi, które dorysowują ją z JavaScriptu.
Krok 5: przebudowa i restart procesu SSR
Osobna pułapka, na której traci się godzinę przy pierwszym podejściu, i nie ma z Magic UI nic wspólnego — po prostu tu wychodzi. Proces inertia:start-ssr wczytuje zbudowany plik raz, do pamięci. Sam npm run build go nie przeładowuje.
Efekt: przeglądarka dostaje HTML ze starymi klasami, a hydracja Reacta nie nadpisuje atrybutów przysłanych z serwera. Widzisz wersję sprzed zmiany, mimo że pliki i CSS są już nowe. Przy animacjach prowadzi to prosto do fałszywego wniosku „komponent nie działa”:
vendor/bin/sail npm run build && vendor/bin/sail artisan inertia:stop-ssrPo zatrzymaniu proces trzeba podnieść ręcznie — supervisor w kontenerze pilnuje tylko PHP-FPM.
Dostępność: cztery komponenty na siedemdziesiąt osiem
To jest najpoważniejszy zarzut wobec Magic UI i nie da się go obejść dobrym słowem. Przeszukaliśmy cały katalog rejestru pod kątem prefers-reduced-motion i useReducedMotion. Trafienia są cztery: dia-text-reveal, icon-cloud, retro-grid i scroll-based-velocity.
Pozostałe siedemdziesiąt cztery animują się zawsze — także u osoby, która w ustawieniach systemu poprosiła o ograniczenie ruchu, bo od animacji parallax dostaje zawrotów głowy albo migotania w polu widzenia. Dla części użytkowników to nie jest kwestia gustu, tylko powód, żeby zamknąć kartę.
Minimum, które trzeba dopisać do arkusza globalnego, zanim pierwszy komponent trafi na produkcję:
@media (prefers-reduced-motion: reduce) {
*, *::before, *::after {
animation-duration: 0.01ms !important;
animation-iteration-count: 1 !important;
transition-duration: 0.01ms !important;
scroll-behavior: auto !important;
}
}To załatwia wszystko, co animuje się w CSS — czyli całą grupę 36 komponentów bez zależności npm oraz większość tych opartych o motion, bo ta biblioteka pod spodem też korzysta z transformacji CSS.
Nie załatwia pętli na canvasie. particles, flickering-grid, retro-grid, icon-cloud, glyph-matrix, globe i confetti rysują klatka po klatce w JavaScripcie i medium query ich nie dotyczy. Tam potrzebny jest jawny warunek:
import { useReducedMotion } from 'motion/react'
const Tlo = () => {
const bezRuchu = useReducedMotion()
if (bezRuchu) {
return <div className="absolute inset-0 bg-linear-to-b from-slate-900 to-slate-950" />
}
return <Particles className="absolute inset-0" quantity={100} />
}Zasada, którą stosujemy u siebie: efekt z canvasu wchodzi na stronę razem ze swoim statycznym zamiennikiem. Jeśli nie ma sensownego zamiennika, to znaczy, że efekt niesie treść — a wtedy nie powinien być efektem.
Uczciwie: to nie jest problem wyłącznie Magic UI. Tak wygląda większość bibliotek animacyjnych. Ale skoro kod trafia do twojego repozytorium, odpowiedzialność za niego przechodzi na ciebie w momencie instalacji, nie przy najbliższej aktualizacji zależności.
Próg wyzwalania animacji przy przewijaniu
Komponenty reagujące na przewijanie — blur-fade, text-animate, number-ticker, box-reveal — opierają się o useInView z motion/react. number-ticker robi to wzorcowo: useInView(ref, { once: true, margin: "0px" }), potem sprężyna z tłumieniem 60 i sztywnością 100, a wartość wpisywana jest wprost do textContent, z pominięciem cyklu renderowania Reacta.
Pułapka pojawia się, kiedy zaczniesz przekazywać amount zamiast margin. amount mierzy procent wysokości elementu, nie ekranu. Przy sekcji trzy razy wyższej od okna przeglądarki — a takie są normą na telefonie — amount: 0.2 znaczy, że animacja ruszy dopiero po przewinięciu ponad połowy widoku. Użytkownik przez pół ekranu ogląda pustkę z opacity: 0.
Próg liczy się od krawędzi okna, nie od elementu:
viewport={{ once: true, amount: 'some', margin: '0px 0px -12% 0px' }}margin trafia wprost do rootMargin obserwatora przecięć, więc ujemne -12% skraca dolną krawędź o mniej więcej dwanaście procent wysokości ekranu. Animacja rusza, gdy element wejdzie w kadr o około sto pikseli — niezależnie od tego, jak wysoka jest sekcja. Ta sama uwaga dotyczy surowych IntersectionObserver z progiem procentowym.
Serwer MCP: komponenty dostępne dla asystenta
Magic UI ma oficjalny serwer Model Context Protocol, który udostępnia katalog komponentów narzędziom wspomagającym pisanie kodu. Zamiast szukać nazwy w dokumentacji, opisujesz efekt.
Instalacja jednym poleceniem, osobno dla każdego środowiska:
npx @magicuidesign/cli@latest install claude
npx @magicuidesign/cli@latest install cursor
npx @magicuidesign/cli@latest install windsurfAlbo ręcznie, wpisem w konfiguracji:
{
"mcpServers": {
"magicuidesign-mcp": {
"command": "npx",
"args": ["-y", "@magicuidesign/mcp@latest"]
}
}
}Po restarcie środowiska działają polecenia w rodzaju „dodaj pionowy marquee z logotypami klientów” albo „wstaw tło z siatką”. Wartość jest konkretna: asystent zna prawdziwe nazwy właściwości i nie wymyśla API, którego nie ma.
Jedna uwaga o utrzymaniu — pakiet @magicuidesign/mcp stoi na wersji 2.0.0 z 9 marca 2026, czyli pół roku bez wydania, podczas gdy sam rejestr komponentów zmieniał się jeszcze w sierpniu. Najnowsze komponenty mogą nie być serwerowi znane. Rejestr shadcn zawsze będzie świeższy.
Magic UI Pro, czyli gdzie jest model biznesowy
Komponenty są na licencji MIT i zostaną darmowe — to jest przynęta, a nie okrojona wersja. Zarabia warstwa wyżej: Magic UI Pro to 199 USD jednorazowo, bez abonamentu, za dziewięć gotowych szablonów stron (agent AI, narzędzie deweloperskie, aplikacja mobilna, SaaS, startup, portfolio, changelog, blog, Codeforge) i ponad pięćdziesiąt sekcji do składania własnych.
Warunki licencji Pro w jednym zdaniu: użycie komercyjne tak, odsprzedaż kodu nie. Dla agencji budującej strony klientom to jest wersja do przeczytania w całości przed zakupem — granica między „użyciem w projekcie klienckim” a „odsprzedażą” bywa w takich licencjach wąska, a nasze zamówienia to zwykle przekazanie repozytorium na własność zamawiającemu.
Część darmowa nie ma tego problemu. MIT to MIT: komercyjnie, w produkcie zamkniętym, z modyfikacjami, bez pytania nikogo o zdanie. Jedyny obowiązek to zachowanie treści licencji — a skoro kod wtapia się w twoje repozytorium, w praktyce oznacza to notę w pliku NOTICE albo w nagłówku skopiowanego komponentu, jeśli twoja firma prowadzi rejestr zależności.
Czy projekt żyje
Żyje, ale ma tempo dojrzałej biblioteki, nie startupu w fazie wzrostu. Sygnały z sierpnia 2026:
- ostatni commit 11 sierpnia, wcześniejsze rozłożone przez cały lipiec — poprawki błędów, nie kolejne warianty gradientów,
- zero otwartych zgłoszeń błędów, dwa otwarte pull requesty ze społeczności,
- zmiany, które ostatnio wchodziły, mówią sporo o priorytetach: przycisk pauzy dla
icon-cloudpod wytyczną WCAG G186, poprawka importów typów, żeby komponenty działały w czystym projekcie Vite z Reactem i TypeScriptem, odświeżenie pliku blokad po alertach Dependabota, bramka CI sprawdzająca build produkcyjny.
To jest profil projektu, który przestał gonić za liczbą komponentów i zaczął pilnować tego, co ma. Dla nas dobra wiadomość — ryzyko, że za pół roku trzeba będzie przepisywać wszystko po zmianie API, jest niskie, tym bardziej że kod i tak leży u nas.
Kiedy to ma sens, a kiedy nie
Ma sens przy stronach sprzedażowych, landing page’ach produktu, portfoliach, dokumentacji z ambicjami wizualnymi, stronach wydarzeń, panelach demonstracyjnych na targi. Wszędzie tam, gdzie użytkownik jest na stronie kilka minut, a wrażenie liczy się tak samo jak treść.
Nie ma sensu w narzędziach, których ktoś używa osiem godzin dziennie. Panel administracyjny, w którym licznik za każdym wejściem odlicza od zera do 1 248, jest po trzecim razie irytujący, a po trzydziestym — powodem zgłoszenia. Do wnętrza aplikacji weź shadcn/ui i zostaw ruch tam, gdzie coś komunikuje: ładowanie, zmiana stanu, potwierdzenie.
Nie ma też sensu tam, gdzie liczy się każdy kilobajt na łączu 3G. Tło z cząsteczkami to pętla animacji na canvasie działająca bez przerwy — na telefonie z niskiej półki widać to na wykresie zużycia baterii, a nie tylko na wykresie klatek.
Podsumowanie
Magic UI jest dobrym narzędziem pod jednym warunkiem: traktujesz go jak zbiór punktów wyjścia, a nie jak zależność. Kod ląduje w repozytorium i od tej chwili jest twój — razem z jego brakami.
- 75 komponentów w rejestrze, 133 gotowe przykłady, całość w 12 tysiącach linii TSX — da się to przeczytać, a nie tylko użyć,
- 36 komponentów bez jednej zależności npm, 31 na
motion; można zbudować całą sekcję i nie powiększyć paczki JS, - instalacja przez narzędzie shadcn, przestrzeń
@magicuirozpoznawana bez konfiguracji, ocena zdrowia rejestru 97,3 na 100, - Laravel z Inertią jest obsługiwany — żaden komponent nie importuje niczego z
next/; potrzebne sącomponents.json, alias@/w Vite i wskazanie własnej funkcjicnw aliasieutils, - serwer MCP daje asystentowi prawdziwe nazwy właściwości zamiast zmyślonych — choć sam pakiet nie miał wydania od marca 2026,
- projekt utrzymywany — ostatni commit w sierpniu 2026, 152 kontrybutorów, zero otwartych błędów.
Trzy rzeczy do zrobienia zanim pierwszy komponent trafi na produkcję: dopisz regułę prefers-reduced-motion do arkusza globalnego (respektują ją tylko cztery komponenty z siedemdziesięciu ośmiu), dopilnuj zgodności majorów motion i framer-motion, i sprawdź w kodzie każdego komponentu z canvasem, czy nie sięga po window poza efektem — jeśli renderujesz po stronie serwera.
Licencja: komponenty open source są na MIT (Copyright © Magic UI) — użycie komercyjne, modyfikacje i produkty zamknięte bez ograniczeń, przy zachowaniu treści licencji. Płatne Magic UI Pro (199 USD jednorazowo, dziewięć szablonów i ponad pięćdziesiąt sekcji) dopuszcza użycie komercyjne, ale zabrania odsprzedaży kodu — przy pracy agencyjnej, gdzie repozytorium przechodzi na własność klienta, warunki warto przeczytać w całości, zanim wystawi się fakturę.