Dlaczego nie od razu framework – czasem platformą jest sama przeglądarka
Doszliśmy do najtrudniejszej części. W pierwszej chodziło o bibliotekę, w drugiej o warstwę – tu chodzi o coś, co dla wielu programistów jest już nie wyborem, lecz domyślnym punktem startu: framework.
Nowy projekt zaczyna się dziś zwykle od pytania „React czy Vue?” – a nie od pytania „czy w ogóle framework?”. A to jest dokładnie ten sam odruch, o którym jest cała seria: raz nauczyliśmy się, że poważny front-end robi się we frameworku, i tak zaczynamy każdy projekt, zanim sprawdzimy, czy ten konkretny go potrzebuje.
Chcę od razu uprzedzić nieporozumienie, bo temat jest zapalny: to nie jest tekst „frameworki są niepotrzebne”. Frameworki rozwiązują realne, trudne problemy i w wielu projektach są jedynym rozsądnym wyborem. Pytanie nie brzmi „framework czy nie”, tylko: czy ten projekt ma problemy, dla których framework powstał? – i o to, żeby to była odpowiedź, a nie odruch.
Po co powstały frameworki
React, Vue czy Svelte rozwiązują jeden trudny problem: synchronizację interfejsu ze zmieniającym się stanem. Kiedy w aplikacji jest dużo danych, które zmieniają się w czasie, i wiele miejsc w interfejsie, które muszą na te zmiany reagować, ręczne aktualizowanie DOM staje się koszmarem. Zapominasz odświeżyć jeden widok, dwa stany rozjeżdżają się między sobą, kod puchnie od if-ów pilnujących spójności.
Framework mówi: opisz, jak interfejs ma wyglądać dla danego stanu, a ja zajmę się aktualizacją DOM, kiedy stan się zmieni. To jest prawdziwa wartość i dla aplikacji typu edytor, arkusz, pulpit z danymi na żywo czy panel administracyjny – wartość ogromna.
Zapamiętaj to kryterium: dużo współdzielonego stanu, który zmienia się w czasie. To ono, a nie „powaga projektu”, decyduje, czy framework się przyda.
Co dziś umie sama platforma
Powód, dla którego w ogóle warto zadać pytanie „czy framework?”, jest taki, że przeglądarka przez ostatnią dekadę dostała narzędzia, które kiedyś dawał tylko framework.
Komponenty: Web Components
Reużywalny komponent z własnym stanem i zamkniętymi stylami – flagowy powód sięgania po framework – platforma ma natywnie:
class LicznikKlikniec extends HTMLElement {
#count = 0;
connectedCallback() {
this.innerHTML = `<button>Kliknięto: <span>0</span></button>`;
this.querySelector('button').addEventListener('click', () => {
this.#count++;
this.querySelector('span').textContent = this.#count;
});
}
}
customElements.define('licznik-klikniec', LicznikKlikniec);<licznik-klikniec></licznik-klikniec>Custom Elements i Shadow DOM (izolacja stylów) są Baseline od lat. To działający, reużywalny komponent bez ani jednej zależności – i użyję go za chwilę w konkretnym przykładzie.
Moduły: system import bez bundlera
Kiedyś dzielenie kodu na pliki wymagało bundlera. Dziś przeglądarka rozumie moduły ES natywnie:
// kalendarz.js
export function nazwaMiesiaca(n) {
return new Intl.DateTimeFormat('pl-PL', { month: 'long' }).format(new Date(2026, n));
}<script type="module">
import { nazwaMiesiaca } from './kalendarz.js';
console.log(nazwaMiesiaca(5)); // "czerwiec"
</script>Dla dużych projektów bundler wciąż ma sens (mniej żądań, optymalizacja). Ale dla małego – to jedna rzecz mniej w łańcuchu narzędzi.
Formatowanie i lokalizacja: Intl
Nazwy miesięcy, daty względne, liczby, waluty, sortowanie zależne od języka – wbudowane, bez paczek:
new Intl.DateTimeFormat('pl-PL', { dateStyle: 'long' }).format(new Date());
new Intl.NumberFormat('pl-PL', { style: 'currency', currency: 'PLN' }).format(1234.5);
// "1234,50 zł"Płynne przejścia: View Transitions
Animowane przejście między stanami czy stronami brało się kiedyś z całego frameworka SPA. Platforma daje to natywnie:
document.startViewTransition(() => zaktualizujWidok());Wariant w obrębie jednej strony jest Baseline (2025); wariant między pełnymi stronami (dla klasycznego MPA) ląduje w przeglądarkach jako cel Interop 2026 – czyli jeszcze przez @supports.
Konkret: ten blog
Nie chcę, żeby to brzmiało teoretycznie, więc najlepszy dowód mam pod ręką. Strona, którą właśnie czytasz, to statyk zbudowany w Astro, serwujący prawie czysty HTML – bez frameworka runtime po stronie klienta. Interaktywne kawałki, które tu są – przełącznik jasny/ciemny, animacje sortowania i struktur danych, frontowa wyszukiwarka wpisów – to pojedyncze skrypty i Web Components, nie aplikacja SPA.
Efekt: strona ładuje się natychmiast, bo nie ma frameworka do pobrania, sparsowania i uruchomienia, zanim cokolwiek się pokaże. A Lighthouse świeci na zielono właśnie dlatego, że najszybszy JavaScript to ten, którego nie ma.
To była świadoma decyzja podjęta przez to kryterium z początku wpisu: blog to treść, nie aplikacja ze współdzielonym stanem. Nie ma tu dużego stanu do synchronizowania między widokami – więc nie ma problemu, który framework by rozwiązywał. Gdybym budował edytor albo pulpit z danymi na żywo, wybór byłby inny i napisałbym to wprost.
Sekcja uczciwości: kiedy framework to właściwy wybór
Ta seria byłaby nieuczciwa, gdyby nie powiedziała jasno, kiedy odpowiedź brzmi „bierz framework”:
- Dużo współdzielonego, zmiennego stanu. To główne kryterium. Edytor, arkusz, pulpit z danymi na żywo, złożony wieloetapowy formularz – ręczna synchronizacja DOM tu nie skaluje się i framework zwraca swój koszt z nawiązką.
- Zespół i utrzymanie. Framework narzuca strukturę, którą zna wielu ludzi. Nowa osoba w projekcie na Reakcie wie, gdzie czego szukać. „Kreatywne” własne rozwiązanie na gołej platformie bywa trudniejsze w utrzymaniu niż standardowy framework, mimo że waży mniej.
- Ekosystem. Gotowe biblioteki komponentów, routing, zarządzanie stanem, narzędzia deweloperskie – jeśli projekt potrzebuje data-grida, virtual-listy i dwudziestu gotowych komponentów, framework z ekosystemem to oszczędność miesięcy.
- SSR i hydration na skalę. Renderowanie po stronie serwera ze złożoną interaktywnością to problem, który frameworki rozwiązały porządnie i którego samemu lepiej nie odtwarzać.
Wspólny mianownik znów jest ten sam co w poprzednich częściach: framework jest właściwym wyborem tam, gdzie problem, dla którego powstał, faktycznie jest w projekcie.
Puenta całej serii
Trzy części, trzy poziomy – biblioteka, warstwa, framework – ale jeden mechanizm w tle. Za każdym razem chodziło o to samo: o narzędzie, które kiedyś rozwiązywało prawdziwy problem, a dziś bierzemy je odruchowo, nie sprawdziwszy, czy problem jeszcze istnieje.
Nie napisałem tej serii po to, żeby kogoś namówić na porzucenie jQuery, JavaScriptu czy Reacta. Napisałem ją przeciw jednej rzeczy – przeciw odruchowi. Bo najgorszy powód, żeby czegoś użyć, brzmi „bo zawsze tak robię”, a najgorszy powód, żeby czegoś nie użyć, brzmi „bo to stare”. Jedno i drugie to ten sam błąd: decyzja podjęta przez nawyk zamiast przez pytanie.
Wróciłem myślami do siebie sprzed lat, broniącego Perla przed PHP z pierwszej części. Nie żałuję, że znałem Perl – żałuję, że tak długo nie zadałem sobie pytania, czy to wciąż najlepsze narzędzie do tego, co robię. Cała ta seria to prośba – głównie do samego siebie – żeby zadawać to pytanie częściej. Do starego i do nowego tak samo.