gdamian.pl
← Wszystkie wpisy
15 min

Astro 7 w praktyce: co realnie zmieniło (Rust, Vite 8, route caching, Advanced Routing) 

Damian GębalaAutor

Astro 7 wyszło 22 czerwca 2026 i to jest wydanie bez nowego komponentu ani nowego słowa kluczowego. Realnie zmieniło cztery rzeczy: kompilator przepisano w Rust, bundler przeszło na Vite 8 z Rolldown, cache tras wyszedł z eksperymentu, a routing zaawansowany przestał być opcją za flagą. Do tego dochodzi zmiana, o której nikt nie pisze w nagłówkach: Astro przestało po cichu naprawiać błędny HTML. Jeśli masz działającą stronę na Astro 5 lub 6, upgrade to dziś jedno polecenie. Jeśli używasz @astrojs/db albo remark pluginów, czytaj dalej, bo to są miejsca, gdzie upgrade naprawdę boli.

Co realnie zmieniło się w Astro 7

Najpierw uczciwe ustawienie. Astro 7 to wydanie silnika, nie interfejsu. Nie ma w nim nowego komponentu, nowego formatu pliku ani nowej nazwy dla integracji. Autorzy frameworka opisali je jako zmiany, które nie dotyczą pisania kodu, tylko tego, co dzieje się pod spodem podczas buildu.

W praktyce wygląda to tak: astro build i astro dev działają szybciej, strona statyczna nadal wysyła do przeglądarki zero JavaScript, a konfiguracja cache i routingu wychodzi z blokady experimental. Dwie funkcje, które wcześniej były eksperymentalne, są teraz po prostu częścią frameworka. Jednocześnie wersja biega na Node 22.12 albo nowszym, a Node 18 i 20 zostały odstawione.

Jeśli prowadzisz stronę na Astro i zastanawiasz się, czy to moment na skok, to krótka odpowź brzmi: tak, jeśli Twój build przechodzi bez ostrzeżeń. Reszta artykułu to konkret: co dokładnie wymieniło się, które zmiany potrafią zepsuć działający projekt i ile z tego przekłada się na realny czas pracy.

Warto też wiedzieć, że aktualna gałąź to 7.3.5, więc między premierą a dziś było już kilkanaście wersji poprawek. Jeśli czytasz porównania z czerwca, to one mogą być nieaktualne.

Kompilator w Rust zamiast Go - i dlaczego teraz wywala błędy w Twoim HTML

Kompilator plików .astro, czyli ten etap, który zamienia Twoje komponenty na JavaScript, napisano od nowa w Rust. Poprzednia wersja w Go zniknęła razem z flagą experimental.rustCompiler, więc jeśli ją ustawiałeś, możesz ją usunąć z astro.config.mjs. Sam kod komponentów piszesz dokładnie tak samo jak wcześniej.

Sama zmiana silnika daje około 6% szybszą kompilację, jeśli liczyć ją osobno. To niewiele. Problem zaczyna się przy liście zmian zachowania, bo nowy kompilator jest wyraźnie ostrzejszy.

Najważniejsza: niezamknięte znaczniki HTML nie są już ignorowane, tylko powodują błąd. Drugie: Astro nie próbuje już poprawiać HTML-a, który jest semantycznie niepoprawny. To świadoma decyzja i moim zdaniem słuszna, bo naprawianie po cichu potrafi dać wynik, którego nikt nie zaprojektował. Praktycznie oznacza to jedno: możesz zobaczyć błąd kompilacji w miejscu, które od lat działało. Błąd jest stary, tylko teraz go widzisz.

Do tego dochodzi zmiana domyślnego zachowania compressHTML. Teraz domyślną wartością jest 'jsx', czyli białe znaki wycinane są według reguł JSX, tak jak robi to React. Odstępy wokół elementów znikają, ale odstęp w środku jednej linii, na przykład między dwoma elementami inline, zostaje. Jeśli któraś spacja Ci zniknie, możesz ją zapisać wprost w kodzie, albo cofnąć zachowanie: compressHTML: true daje kompresję świadomą HTML-a, a compressHTML: false zostawia wszystkie białe znaki. To ustawienie, które warto ruszyć od razu, zanim zaczniesz szukać przyczyny dziwnych odstępów w menu lub w treści.

Vite 8 i Rolldown - bundler przestaje być wąskim gardłem

Astro przeszło na Vite 8, który wchodzi z bundlerem Rolldown napisanym w Rust. Rolldown zastępuje wcześniejsze połączenie esbuild i Rollup, a bundlowanie było jednym z najwolniejszych etapów każdego buildu. Przeniesienie go na jeden silnik w Rust usuwa wąskie gardło, które ciągnęło się przez lata.

Tu ważna uwaga metodologiczna. Zakres 15 do 61 procent szybszych buildów, który pojawia się w materiałach o tej premierze, pochodzi z benchmarków zespół Astro. To nie jest pomiar Twojego projektu i nie zobaczysz gwarancji, że Twoja strona zyska dokładnie tyle. Nie ma też publicznej tabeli z maszyną testową i opisem projektu, na którym te liczby powstały.

O randze zmiany możesz się przekonać z gałęzi 7.3.x: tam osobna poprawka skróciła czas startu astro dev o około jedną trzecią w projektach z konfiguracją kolekcji treści. To nie jest rewolucja, to jest dokładnie ten profil zmian, które odczuwasz jako codzienność: krócej czekasz na podgląd, krócej czekasz na build wdrożenia.

Jeśli trzymasz na Astro, ten temat może być Ci bliższy niż wszystkie inne, bo wcześniej pisałem o tym, jak Twoja strona znika z wyników, gdy zmienia się sposób prezentacji wyszukiwarki. Szybszy build sam w sobie nie poprawia pozycji, ale pozwala częściej wdrażać poprawki, które pozycję realnie zmieniają.

Sätteri domyślnym procesorem Markdown

Pliki .md są teraz renderowane przez Sätteri, natywny procesor Markdown napisany w Rust, a nie przez łańcuch remark i rehype. Pakiet @astrojs/markdown-remark nie jest już instalowany domyślnie.

Skala tego zysku zależy od tego, ile masz treści w Markdown. Skarż nie jest teorią: strona z dokumentacją Astro odzyskała ponad minutę czasu buildu po przejściu na Sätteri. Przy typowym serwisie z kilkudziesięcioma wpisami nie zobaczysz minuty, ale zobaczysz różnicę przy każdym wdrożeniu.

Jest jedno miejsce, w którym musisz być świadomy decyzji. Jeśli używasz markdown.remarkPlugins, markdown.rehypePlugins albo markdown.remarkRehype, to przejście na Sätteri je zmienia. Opcje nadal działają, ale wymagają zainstalowania @astrojs/markdown-remark. Wybór jest prosty: zostawiasz remark i ustawiasz markdown.processor na unified(), albo przenosisz wtyczki na nowy procesor. To jedyna decyzja w całym upgrade, którą warto podjąć świadomie, a nie zautomatyzować.

Route caching wyszedł z eksperymentu - konkretna konfiguracja

Cache tras, eksperymentalny od wersji 6.0.0, jest teraz stabilny. Flagi experimental.cache i experimental.routeRules zniknęły, a w ich miejsce są opcje najwyższego poziomu cache i routeRules. Konfiguracja wygląda tak:

import { defineConfig, memoryCache } from 'astro/config';

export default defineConfig({
  cache: {
    provider: memoryCache(),
  },
  routeRules: {
    '/blog/[...path]': { maxAge: 300, swr: 60 },
  },
});

W plikach .astro dyrektywy ustawiasz przez Astro.cache, a w trasach API i w middleware przez context.cache. Jeśli nie chcesz dotykać kodu tras, reguły da się zadeklarować właśnie w routeRules. Sąd po stronie serwera tłumaczy je na nagłówki albo na zachowanie runtime zależnie od providera, którego używasz.

Warto wiedzieć o dwóch ograniczeniach wbudowanego memoryCache(), bo potrafią zaskoczyć. Po pierwsze, odpowiedzi z nagłówkiem Vary: Cookie lub Vary: * są pomijane. Po drugie, odpowiedzi, które ustawiają cookies przez Astro.cookies albo Astro.session, nie są w ogóle zapisywane. Oba zachowania zostały naprawione w patchach 7.2.5 i 7.3.0, więc na 7.3.5 masz już poprawne wersje.

Osobno, bo często się myli: cache na CDN od Netlify, Vercel i Cloudflare nadal jest eksperymentalny. Zespół Astro wydał do niego pomocnicze narzędzia do budowania nagłówków cache i tagów unieważniających, ale stabilne API dotyczy cache odpowiedzi, nie cache na brzegu sieci.

Advanced Routing i src/fetch.ts - routing bez flagi eksperymentalnej

To druga funkcja, która wyszła z eksperymentu. Zaawansowany routing, wprowadzony za flagą w 6.3.0, jest teraz włączony domyślnie i daje pełną kontrolę nad tym, jak żądania przechodzą przez aplikację, zanim w ogóle trafią do trasy. Zakres możliwości, o którym mówią źródła: przepisywanie adresów, manipulacja nagłówkami, odpowiedzi warunkowe, testy A/B na brzegu, uwierzytelnianie i własne strony błędu. Jest zgodny ze stylem middleware z Hono, więc jeśli znasz tę konwencję, nie uczysz się nowej.

Zmiana nazwy pliku jest najczęstszą przyczyną zaskoczenia. Domyślnym entrypointem jest teraz src/fetch.ts, a nie src/app.ts. Jeśli używałeś tego za flagą bez własnego entrypointu, masz dwa wyjścia: zmieniasz nazwę pliku na src/fetch.ts albo ustawiasz fetchFile i zostawiasz swoją nazwę. fetchFile to teraz opcja najwyższego poziomu, nie element experimental. I jedno wyłączenie: jeśli src/fetch.ts zajmuje Ci się czymś innym, ustawiasz fetchFile: null.

Pozostała zmiana dotyczy własnych integracji, nie samej strony. Publiczne API zaawansowanego routingu zostało zawężone: state.provide(), state.resolve(), state.finalizeAll() i App.Providers są teraz wewnętrzne. Jeśli dzieliłeś stan między handlerami w integracji, masz zastępstwo: locals do stanu na czas jednego żądania.

Przy stronie czysto statycznej nie potrzebujesz tego ani trochę. Jeśli natomiast robisz portal, w którym część tras ma przechodzić przez sprawdzenie uprawnień przed zapytaniem do API, albo chcesz własną stronę 404 z podpowiedzią podobnych adresów, to jest dokładnie ten haczyk, którego wcześniej brakowało.

Dev server w tle, bo pracuję z agentem kodującym

To zmiana, która nie dotyczy Twojej strony, tylko mojej codziennej pracy, więc powiem wprost. Gdy Astro wykryje agenta kodującego, astro dev startuje dev server jako odłączony proces w tle. Powstaje plik blokady .astro/dev.json z adresem, portem i numerem procesu, żeby nie odpalić drugiego serwera dla tego samego projektu.

Do tego dochodzą cztery podkomendy, których wcześniej nie było: astro dev --background, żeby uruchomić w tle jawnie, astro dev stop, astro dev status oraz astro dev logs z --follow do strumieniowania logów na żywo. Dzięki temu „a co wypisał build" przestaje być pytaniem do użytkownika, bo logi da się odczytać maszynowo.

Są dwa szczegóły, o których warto wspomnieć. Jeśli nie pracujesz z agentem, astro dev zachowuje się dokładnie jak wcześniej i nie musisz nic robić. Jeśli chcesz wyłączyć tryb tle mimo wykrycia agenta, ustawiasz zmienną środowiskową ASTRO_DEV_BACKGROUND na 0. Na Windowsie tryb tle jest domyślnie wyłączony dla agentów, więc trzeba podać --background jawnie.

Szerszy kontekst pracy z AI przy kodzie opisałem osobno w tekście o tygodniu pracy z Claude przy programowaniu. Tam jest o tym, co realnie przyspiesza, a co tylko wygląda jak przyspieszenie.

Co się zepsuje przy upgrade - lista zmian łamiących kompatybilność

Nie będę tu rozwlekał, bo lista jest konkretna i warto ją przejrzeć przed upgrade, a nie po nim.

Astro przestało naprawiać błędny HTML po cichu. To opisałem wyżej, ale powtarzam, bo to jedyna zmiana, która potrafi zatrzymać build na dużym projekcie. Zanim zaczniesz, zrób jeden build na obecnej wersji i sprawdź, czy jest czysty. To warunek, który stosuję przy każdym takim skoku.

@astrojs/db zostało usunięte. Pakiet był deprecated od 6.4.5, a teraz zniknął razem z komendami astro db, astro login, astro logout, astro link i astro init. Zespół Astro wprost proponuje trzy zamienniki: wbudowany w Node moduł node:sqlite, dostępny od Node 22.5.0, Drizzle ORM albo dowolną inną bibliotekę bazy. Jeśli używałeś Astro DB, to nie jest upgrade, tylko część projektu do napisania od nowa.

Wymagania Node. Astro 7 wymaga Node 22.12 albo nowszego, a Node 18 i 20 nie są wspierane. Jeśli Twój hosting jest przypięty do starszej wersji, to jest blokada, nie utrudnienie. Zaznaczam, że tę liczbę znalazłem w artykule porównawczym, a changelog nie podaje minimalnej wersji Node dla tej edycji, więc przed skokiem sprawdź ją w swoim środowisku.

Deprecated API z astro:transitions zniknęły. Używałeś createAnimationScope albo stałych TRANSITION_BEFORE_PREPARATION, TRANSITION_AFTER_PREPARATION, TRANSITION_BEFORE_SWAP, TRANSITION_AFTER_SWAP, TRANSITION_PAGE_LOAD i dwóch funkcji sprawdzających zdarzenia? Trzeba to przepisać na nazwy zdarzeń wprost, na przykład event.type === 'astro:before-preparation'. Skoro to mało kto robi, szukam tego jednym grep po repo, nie przeglądem plik po pliku.

Trzy mniejsze, ale potrafiące zatrzymać CI. Minimalna wersja Sharp idzie do 0.35.4, generowane wartości compatibility_date dla Cloudflare wymagają Wrangler 4.125.0 albo nowszego, a TypeScript 7 nie jest jeszcze obsługiwany i polecenie typowania podpowiada eksperymentalną ścieżkę przez @astrojs/ts-content-mapper. Do tego własne adaptery mogą używać app.pipeline.getLogger(), a to API usunięto w 7.2.3; zamiennikiem jest app.getLogger().

Jest jeszcze jedna rzecz, która jest zmianą, a nie błędem, ale potrafi zaskoczyć: jeśli ustawiałeś build.concurrency na 1, żeby incremental buildy nie wyłączały cache, to ten workaround możesz usunąć. Od 7.3.0 incremental buildy obsługują renderowanie równoległe i cache zostaje włączony.

Ile realnie zarabiasz na szybszym buildzie

Skoro nie mam tabeli z oficjalnych benchmarków, to podam tylko liczby, które da się sprawdzić, i wskażę, skąd pochodzą.

Najczęściej powtarzany zakres to 15 do 61 procent szybszych buildów. Dwa niezależne źródła podają dokładnie ten sam zakres, ale inaczej go opisują: jedno mówi o oficjalnych benchmarkach, drugie o realnych projektach. To nie jest ta sama podstawa, więc nie traktuj tego jako jednej twardej liczby.

Konkretny przykład z projektu, który opisał autor bloga: strona z około 80 trasami, w większości Markdown, budowała się w około 12 sekund, a po zmianie w 5 sekund. To dokładnie 2,4 raza, czyli zgadza się z drugą liczbą z tej serii, bo nowy silnik renderujący podaje około 2,4 raza szybsze renderowanie. Jeśli przeliczę widełki 15-61% na ten konkretny przypadek, wychodzi 7,2 do 4,7 sekundy, czyli Twój wynik może być gdzieś pomiędzy. Nie obiecuję dolnej granicy.

Skąd bierze się to 2,4 raza: renderowanie przebudowano na kolejkę zamiast głębokiej rekurencji, co poza szybkością ogranicza też ryzyko uderzenia w limit stosu na dużych stronach. Osobno sam kompilator daje około 6%, a przetwarzanie Markdown na Sätteri odzyskało ponad minutę na stronie dokumentacyjnej Astro.

Jest jeszcze jeden efekt, którego nie wyliczę, bo nie mam danych: mniejszy cache builda. W jednym z pomiarów porównawczych wyszedł 42,45 MB przy Astro wobec 103,75 MB przy Next.js, czyli 59% mniej. Jeśli trzymasz buildy na dysku i liczysz transfer, to jest różnica, którą warto przeliczyć na własne liczby. Przy kosztach utrzymania środowiska developerskiego zagadnienie jest już opisane osobno, w tekście o realnym koszcie samodzielnego hostingu miesięcznie.

Astro 7 kontra Next.js 16.3 - co w porównaniu naprawdę się ruszyło

Krótko, bo szczegółowe porównanie obu frameworków na trzech stronach masz osobno: Astro vs Next.js w 2026. Tu tylko to, co zmieniło się w samym porównaniu.

Struktura zostaje taka sama: strona statyczna w Astro wysyła 0 KB JavaScriptu, a typowa strona w Next.js około 85-100 KB po kompresji, z Lighthouse 95-100 w Astro wobec 85-95 w Next.js. Nadal nie ma w Astro streamingu SSR ani ISR z revalidacją. Nadal każda wyspa hydatuje się osobno, więc stan między wyspami wymaga zewnętrznego magazynu. To decyzje architektoniczne sprzed premiery, nie skutki niej.

Co się zmieniło, to fakt, że Next.js też mocno poszedł w Rust. Turbopack, bundler w Rust, jest w Next.js 16 stabilny i domyślny, a autorzy porównania podają dla niego 2-5 razy szybsze buildy produkcyjne. To ta sama droga, innymi słowy. Różnica jest taka, że Astro zaczął od Vite 8, a Next.js dogania bundlerem własnym, i dlatego liczby 15-61% i 2-5 razy mówią o zupełnie różnych rzeczach. Nie dziel ich przez siebie, bo to nie jest ta sama miara.

Jedno ostrzeżenie o danych, bo łatwo tu nadrobić sobie fałszywą pewność. Pomiary czasu buildu, liczby pakietów i rozmiaru cache, które krążą w porównaniach, zrobione na Astro 6.4 i nie zostały powtórzone na 7. Sam autor tego porównania zaznacza, żeby traktować je jako orientacyjne. Nie będę ich powtarzał jako wyniku dla Astro 7, bo to byłoby dopisanie liczb, których nikt nie zmierzył na nowej wersji.

Kiedy upgrade ma sens, a kiedy to strata dnia

Krótka decyzja, oparta na tym, co faktycznie zmieniło się w tej edycji.

Upgrade jest prosty, gdy: jesteś na Astro 5 lub 6, Twój build przechodzi bez ostrzeżeń, nie używasz @astrojs/db i nie opierasz się na wtyczkach remark. Wtedy to instalacja najnowszej wersji i jeden npm run build. Autor jednego z przewodników zrobił tak pięć projektów klientów i jedyną poprawką, jakiej potrzebował, było podniesienie @astrojs/sitemap do pasującej wersji.

Upgrade wymaga dnia, gdy: jesteś na Astro 3 lub starszym. Wtedy dochodzą Content Collections, zmiana Content Layer i dopiero potem to wydanie. To nie jest pięciominutowa robota, tylko zarezerwowany popołudnie. Jeśli dodatkowo używasz @astrojs/db albo remark pluginów, dokładam do tego osobne zadanie, bo to już nie jest aktualizacja, tylko praca nad kodem.

Upgrade odwłóż, gdy: hosting jest przypięty do Node starszego niż 22.12 albo projekt nie ma kompletnego testu wdrożenia. Aktualizacja silnika bez możliwości szybkiego cofnięcia to nie jest wygoda, tylko ryzyko. Wtedy ustawiasz aktualizację jako osobne zadanie z osobnym terminem, a nie jako część innej pracy.

Przy okazji, jeśli prowadzisz WordPressa i rozważasz Astro jako front, mamy rozpisany konkretny przepis na połączenie CPT i ACF ze szybkim frontem. Tam jest też realna cena takiego podejścia, a nie tylko architektura.

7.3.x w praktyce - znane regresje, które warto znać przed wdrożeniem

Gałąź 7.x ma długi ogon poprawek i to jest normalne przy zmianach tak głębokich jak nowy kompilator i nowy bundler. Kilka pozycji z changeloga warto jednak znać, bo dotyczą rzeczy, które wykańczały projekty.

W 7.2.5 naprawiono memoryCache(), który zapisywał odpowiedzi ustawiające cookies, oraz transition:persist, który przestał działać dla <audio> i <video>. W 7.2.7 poprawiono rewrite() i next(payload) dla żądań GET i HEAD z body dostarczanym przez hosta. W 7.3.3 naprawiono przekierowania, których cel psuł się, gdy parametr trasy dynamicznej zawierał wzorzec typu $&. W 7.3.2 i 7.3.0 poprawiono routing fallback i18n, który zamieniał fragment ścieżki, gdy kod języka pojawiał się też na początku kolejnego segmentu, na przykład /es/enterprise stawało się /es/esterprise.

Dwie rzeczy, które wybijają po cichu. Incremental buildy potrafiły podać zapisany HTML z nazwami plików CSS, których już nie ma, czyli po zmianie samego arkusza stylów serwował stary CSS; naprawiano to w 7.2.5 i 7.3.3. Przy dużym wspólnym grafie zależności incremental buildy potrafiły gwałtownie zwalniać, co poprawiono w 7.2.2. Jeśli pracujesz z dużą kolekcją treści i zależy Ci na czasie wdrożenia, to są dokładnie te miejsca, które warto zmierzyć na swoim projekcie, zamiast ufąć cudzym liczbom.

Przy okazji warto ogarnąć, gdzie leży próg utrzymania Node, bo to on decyduje, jak długo zostaniesz na 7.x. W 7.2.5 zaktualizowano komunikaty o deprecated API tak, by kierowały do migracji na Astro 8, co znaczy, że lista wycofań się formuje. Aktualnie rekomendowany próg to Node 22.12, a node:sqlite, jeśli kiedyś wrócisz do wbudowanej bazy, wymaga 22.5.0.

Co bym zrobił na Twoim miejscu

Krótka lista decyzji, w kolejności, w której bym ją podjął.

Najpierw sprawdź środowisko: Node 22.12 albo nowszy, hosting bez przypięcia do starej wersji. Jeśli to nie przechodzi, upgrade odpada i nie ma o czym dalej rozmawiać.

Potem zrób build na obecnej wersji i przeczytaj jego wyjście. Jeśli są ostrzeżenia, nie zaczynaj. Nowy kompilator jest surowszy przy HTML-u i pierwszy build po migracji pokaże rzeczy, które działały latami. Lepiej wiedzieć o tym wcześniej.

Sprawdź, czy używasz @astrojs/db albo remark pluginów. Jeśli tak, to nie jest jedno polecenie, tylko osobne zadanie z zakresem.

Dopiero potem wspinaj cache i routeRules poza experimental. To jest najbardziej namacalny zysk z tej wersji dla strony, która ma część tras renderowanych na żądanie.

A src/fetch.ts zostaw na później, dopóki nie masz realnego powodu: uwierzytelniania na części tras albo własnej strony 404 z podpowiedzią. Przy czysto statycznej stronie to dodatkowa konfiguracja bez efektu, a kod, którego nie używasz, tylko utrudnia utrzymanie.

Jeśli chcesz przejść tę ścieżkę ze mną, napisz. Odpowiadam zwykle tego samego dnia i zaczynamy od jednego konkretnego pytania: co dziś kosztuje Cię najwięcej czasu przy utrzymaniu strony.

Robisz coś podobnego u siebie?Napisz do mnie

Masz proces, który zjada tydzień pracy? Odzyskajmy ten tydzień.

Napisz do mnie