Przepisy UI dla React Native i Flutter
Przepisy UI dla React Native i Fluttera to 12 promptów do wklejenia, z którymi Claude Code, Codex lub Cursor budują wieloplatformowe ekrany mobilne, od adaptacyjnej nawigacji po przygotowanie do sklepów. Każdy prompt przypina wersje główne pakietów aktualne we wrześniu 2026 i żąda dowodów z obu platform, więc sprawdzasz zrzuty ekranu i testy zamiast czytać każdą linijkę.
Ta strona jest dla programistów, którzy budują UI mobilne z agentem, i dla tech leadów, którzy przeglądają to, co agent wydaje. Prosisz o przesuwaną kartę i dostajesz Gesture.Pan(), które react-native-gesture-handler 3 oznacza jako przestarzałe. Prosisz o szybką listę wpisów (feed) i dostajesz estimatedItemSize z FlashList, a FlashList 2 usunął ten prop. Na symulatorze iOS wszystko wygląda dobrze, a emulatora Androida nikt nie otwiera. Ta strona dotyczy ekranów; przepisy dla stosu pod nimi (buildy Expo i aktualizacje OTA, warstwa danych React Native, architektura z Riverpodem i go_routerem) zaczynają się w przeglądzie rozwoju mobilnego.
Jakie wersje pakietów zakładają te przepisy?
Dział zatytułowany „Jakie wersje pakietów zakładają te przepisy?”Dane treningowe agenta obejmują kilka wersji głównych każdego pakietu poniżej, a każda z nich zmieniła API, po które agent chętnie sięga. Tabela pokazuje, co npm i pub.dev serwowały 26 września 2026. Wpisz wersje główne do AGENTS.md (lub CLAUDE.md), żeby dziedziczyła je każda sesja, a dokładne wersje niech wybierają npx expo install lub flutter pub add.
| Pakiet | Wersja | Co agent robi źle |
|---|---|---|
react-native | 0.87.1 | Moduły mostkowe starej architektury. Aktualne biblioteki, takie jak Reanimated 4, celują w New Architecture. |
@react-navigation/native | 7.4.1 | Miesza styl konfiguracji v6 i v7 w jednym nawigatorze. |
@shopify/flash-list | 2.3.2 | estimatedItemSize. Wersja 2 sama mierzy elementy, a tego propa już nie ma. |
react-native-reanimated | 4.7.0 | Brak react-native-worklets (zależność peer 0.13.x). Reanimated 4.7 wymaga też React Native od 0.86 do 0.88. |
react-native-gesture-handler | 3.3.0 | Gesture.Pan(), które 3.x oznacza jako @deprecated na rzecz usePanGesture. Linia 2.x żyje na npm pod tagiem legacy. |
expo-image | 57.0.5 | Sięga po react-native-fast-image. Ta strona używa expo-image. |
expo-notifications | 57.0.21 | Sięga po @notifee/react-native, którego ostatnie wydanie na npm to 9.1.8 z 20 grudnia 2024. |
flutter_riverpod | 3.4.3 | StateNotifierProvider z Riverpoda 2, który Riverpod 3 przeniósł do legacy.dart. |
go_router | 18.0.1 | Ignoruje minimalną wersję SDK. Wersja 18 wymaga Fluttera 3.44 i Darta 3.12. |
Skonfiguruj agenta raz do pracy nad UI mobilnym
Dział zatytułowany „Skonfiguruj agenta raz do pracy nad UI mobilnym”Dwie rzeczy obniżają koszt weryfikacji każdego przepisu poniżej: sprawdzanie typów po każdej edycji i plik instrukcji, który definiuje „gotowe”. Najpierw zainstaluj umiejętności (skills) od twórców swojego stosu. Przegląd rozwoju mobilnego zawiera polecenia instalacji skilli Expo, Fluttera i Callstack React Native oraz MobileBuildMCP.
Dodaj ten blok do AGENTS.md, który Codex czyta w zaufanych projektach. Claude Code czyta go, gdy repozytorium nie ma CLAUDE.md (od v2.1.277, kanał wydań latest na 26 września 2026); w przeciwnym razie skopiuj blok do CLAUDE.md. W Cursorze wklej blok do reguły projektu (Rule).
## Mobile UI: verify before done- Pinned majors: React Native 0.87, React Navigation 7, FlashList 2, Reanimated 4, Gesture Handler 3, expo-image, expo-notifications. Flutter 3.44+, Riverpod 3, go_router 18.- Before using a library API, read its types in node_modules or its pub.dev docs.- Gates: `npx tsc --noEmit`, the linter, and the test runner (React Native); `flutter analyze` and `flutter test` (Flutter).- Launch the app on one iOS simulator and one Android emulator. Save a screenshot of every changed screen to evidence/<task>/ios-*.png and evidence/<task>/android-*.png.- Forbidden in app code: localStorage, window.*, document.*, dart:html, dart:io Platform in widgets.- Never run a store submission, EAS build, or OTA publish.Narzędzia różnią się tym, jak egzekwują ten blok:
Hook PostToolUse pokazuje Claude’owi błędy typów przy tej edycji, która je spowodowała. Zapisz to jako .claude/hooks/mobile-typecheck.sh i nadaj prawo wykonywania:
#!/usr/bin/env bash# .claude/hooks/mobile-typecheck.sh (PostToolUse, matcher "Edit|Write")set -uo pipefailfile=$(jq -r '.tool_input.file_path // empty')case "$file" in *.ts|*.tsx) out=$(cd "$CLAUDE_PROJECT_DIR" && npx tsc --noEmit 2>&1) \ || { echo "tsc failed after editing $file:" >&2; head -n 40 <<<"$out" >&2; exit 2; } ;; *.dart) out=$(cd "$CLAUDE_PROJECT_DIR" && dart analyze "$file" 2>&1) \ || { echo "dart analyze failed on $file:" >&2; head -n 40 <<<"$out" >&2; exit 2; } ;;esacexit 0Zarejestruj go w .claude/settings.json:
{ "hooks": { "PostToolUse": [ { "matcher": "Edit|Write", "hooks": [{ "type": "command", "command": "${CLAUDE_PROJECT_DIR}/.claude/hooks/mobile-typecheck.sh", "args": [], "timeout": 120 }] } ] }}Matcher filtruje po nazwie narzędzia, a nie po wzorcu pliku, dlatego skrypt sam filtruje po rozszerzeniu. W dużym projekcie to pełne sprawdzanie typów po każdej edycji może trwać kilkadziesiąt sekund; timeout 120 sekund nie pozwala, żeby wolny przebieg zablokował sesję, a dodanie --incremental do wywołania tsc pozwala kolejnym przebiegom korzystać z poprzednich informacji o typach. Pełna lista zdarzeń jest na stronie o hookach Claude Code. Przed scaleniem uruchom /code-review na gałęzi.
Codex czyta blok z AGENTS.md w każdej sesji. Żeby powtarzalnie i bez nadzoru uruchomić jeden przepis, użyj codex exec z profilem uprawnień :workspace (beta w Codex 0.157.1). Ten profil nie ma dostępu do sieci i zapisuje tylko w projekcie i w katalogu tymczasowym (nie może pisać do $HOME): w naszym teście Codeksa 0.157.1 na Linuksie curl do rejestru npm nie rozwiązał nazwy hosta, a zapis do $HOME trafił na system plików tylko do odczytu. Instalacja pakietów w takim przebiegu się nie uda, podobnie jak wszystko, co potrzebuje stanu symulatora lub emulatora spoza repozytorium. Ten przebieg z bramkami offline przetestowaliśmy tylko dla bramek npm i TypeScriptu. Fluttera tu nie testowaliśmy: flutter analyze i flutter test mogą wymagać zapisywalnego katalogu SDK i $HOME, a więc innego profilu. Zainstaluj więc zależności wcześniej, zleć Codeksowi tylko bramki działające offline i oznacz przebieg jako nieudany, jeśli którakolwiek bramka nie zgłosi PASS:
npm ci # Flutter (untested here): flutter pub get. The :workspace profile has no networkmkdir -p evidence/feed-listcodex exec -c default_permissions=":workspace" -o evidence/feed-list/summary.md \ "Apply the FlashList recipe in docs/prompts/feed-list.md. Do not install packages. Run the type check, linter and tests from 'Mobile UI: verify before done' in AGENTS.md; skip the simulator, emulator and frame-rate steps. Report each gate on its own line as PASS, FAIL or NOT RUN with the reason."s=evidence/feed-list/summary.mdtest -s "$s" && grep -q PASS "$s" && ! grep -Eq 'FAIL|NOT RUN' "$s" \ || { echo "Codex run incomplete or failing: see $s" >&2; exit 1; }Najpierw zapisz prompt dla FlashList z tej strony jako docs/prompts/feed-list.md. Sprawdzenie domyka się bezpiecznie: brakujące lub puste podsumowanie, FAIL albo NOT RUN przerywa skrypt. Dowody z urządzeń zbierasz sam: uruchom aplikację na symulatorze iOS i emulatorze Androida poza Codeksem, zapisz zrzuty ekranu w evidence/feed-list/ i sam zmierz liczbę klatek. Zielony summary.md nie jest dowodem z urządzenia.
Otwórz pull request i skomentuj @codex review, żeby dostać drugi przegląd diffu według tych samych reguł z AGENTS.md. Zobacz przegląd kodu w Codeksie.
Wklej blok do reguły projektu (Rule), żeby Cursor stosował go w każdej sesji. Przepisy, które dotykają wielu plików (nawigacja, moduły natywne), zaczynaj w Plan Mode, żeby zatwierdzić listę plików, zanim agent napisze kod. Na pull requeście diff przegląda Bugbot. Pętlę po stronie IDE z symulatorami opisuje przewodnik Cursora po rozwoju mobilnym.
Przepisy UI dla React Native
Dział zatytułowany „Przepisy UI dla React Native”Każdy przepis opisuje sytuację, podaje prompt i nazywa dowód, który potwierdza wynik. Wklejaj prompty bez zmian, edytuj tylko nazwy ekranów.
Zbuduj nawigację adaptacyjną z React Navigation 7
Dział zatytułowany „Zbuduj nawigację adaptacyjną z React Navigation 7”Zespół produktowy chce dolnego paska zakładek na iOS i szuflady nawigacyjnej na Androidzie, obu opartych na tych samych ekranach i tych samych deep linkach.
Dowód: testy deep linków i zrzuty ekranu profilu 42 otwartego z linku na obu platformach.
Zbuduj responsywny układ na telefony, tablety i składane urządzenia
Dział zatytułowany „Zbuduj responsywny układ na telefony, tablety i składane urządzenia”Aplikacja rozciąga układ telefonu na tablet, a ekrany lista-szczegóły marnują dwie trzecie wyświetlacza.
Dowód: trzy testy punktów przerwania i zrzut ekranu tabletu w każdej orientacji. To przy obrocie psują się sztywno wpisane szerokości.
Napraw przycinającą się listę wpisów z FlashList 2 i expo-image
Dział zatytułowany „Napraw przycinającą się listę wpisów z FlashList 2 i expo-image”Lista wpisów ma ponad 1000 elementów z obrazkami, przycina się przy przewijaniu, a pull-to-refresh przeskakuje listę.
Dowód: liczba klatek na sekundę przed i po, z tego samego urządzenia i tego samego przewijania, a nie „powinno być szybciej”. Warstwę danych za listą wpisów opisuje przepis dla React Native.
Pokaż stan offline, nie tracąc pracy użytkownika
Dział zatytułowany „Pokaż stan offline, nie tracąc pracy użytkownika”Technicy w terenie wypełniają formularze bez zasięgu, a dziś aplikacja pokazuje spinner w nieskończoność i gubi wpis.
Dowód: test przejścia z offline do online oraz zrzut ekranu banera i znacznika zrobiony w trybie samolotowym. Silnik przechowywania i synchronizacji (MMKV z TanStack Query albo WatermelonDB do synchronizacji relacyjnej) opisuje przepis dla React Native.
Napisz moduł natywny, gdy żadna biblioteka nie obsługuje sprzętu
Dział zatytułowany „Napisz moduł natywny, gdy żadna biblioteka nie obsługuje sprzętu”Dostawca sprzętu NFC używa własnego formatu tagów, którego react-native-nfc-manager nie udostępnia, więc potrzebujesz kodu w Swifcie i Kotlinie za typowanym API w TypeScripcie.
Dowód: dwa czyste buildy natywne i testy hooka. CoreNFC nie działa na symulatorze iOS, więc przed scaleniem człowiek skanuje prawdziwy tag jednym iPhone’em i jednym telefonem z Androidem. W aplikacji Expo poproś o moduł Expo; zobacz przepis dla Expo.
Edycje natywne wymagają przebudowania, a nieaktualna binarka sprawia, że poprawna zmiana wygląda na zepsutą. Po każdej edycji pliku .swift lub .kt każ Claude’owi przebudować aplikację natywną: npx expo run:ios / npx expo run:android w buildzie deweloperskim Expo albo cd ios && pod install, a potem npx react-native run-ios / npx react-native run-android w czystym React Native. pod install tylko synchronizuje zależności i niczego nie kompiluje. npx expo prebuild --clean zostaw na zmianę pluginu konfiguracji lub app.json w projekcie z Continuous Native Generation: regeneruje ios/ i android/ i usuwa wszystkie bezpośrednie edycje w tych katalogach, dlatego kod natywny w aplikacji Expo należy do modułu Expo. Na macOS MobileBuildMCP pozwala Claude’owi samodzielnie budować, uruchamiać symulator i czytać log builda.
Uruchamiaj pracę natywną w osobnym worktree, żeby stan synchronizacji Xcode i Gradle nigdy nie mieszał się z gałęzią JavaScriptu. Każ Codeksowi kończyć każdą edycję natywną tym samym przebudowaniem: npx expo run:ios / run:android (Expo) albo pod install, a potem npx react-native run-ios / run-android (czysty React Native). MobileBuildMCP rejestrujesz przez codex mcp add; polecenie znajdziesz na stronie o serwerach MCP dla serwerów deweloperskich.
Najpierw zatwierdź listę plików w Plan Mode: specyfikację, klasę w Swifcie, klasę w Kotlinie, manifest, entitlement i hook. Brakujący plik entitlementu to najczęstsze przeoczenie, a wychodzi na jaw dopiero przy uruchomieniu na urządzeniu.
Zbuduj stos przesuwanych kart z Reanimated 4 i Gesture Handler 3
Dział zatytułowany „Zbuduj stos przesuwanych kart z Reanimated 4 i Gesture Handler 3”Ekran dopasowań potrzebuje stosu kart, który podąża za palcem z częstotliwością odświeżania ekranu i nie przycina się, gdy JavaScript jest zajęty.
Dowód: testy gestów oraz nagranie ekranu z fizycznego telefonu z Androidem, na którym widać zgubione klatki ukrywane przez symulator. Sprawdź, czy react-native-worklets jest w package.json.
Poproś o zgodę na powiadomienia we właściwym momencie
Dział zatytułowany „Poproś o zgodę na powiadomienia we właściwym momencie”Aplikacja prosi o zgodę na powiadomienia przy pierwszym uruchomieniu, większość użytkowników odmawia, a stuknięte powiadomienie otwiera ekran główny zamiast zamówienia, o którym mówi.
Dowód: testy maszyny stanów oraz powiadomienie wysłane na urządzenie i stuknięte przy zamkniętej aplikacji. Potok tokenów i stronę serwerową opisuje przepis dla Expo.
Przepisy UI dla Fluttera
Dział zatytułowany „Przepisy UI dla Fluttera”Przepisy dla Fluttera używają API widgetów i stanu z Fluttera 3.44+ i Riverpoda 3. Konfigurację pakietów, architekturę providerów i przekierowanie autoryzacji w go_routerze zrób najpierw według przepisu dla Fluttera.
Zbuduj markową bibliotekę widgetów dopasowaną do platformy
Dział zatytułowany „Zbuduj markową bibliotekę widgetów dopasowaną do platformy”Każdy ekran sam styluje swoje przyciski, tryb ciemny jest skończony w połowie, a zespół projektowy nie widzi wszystkich wariantów w jednym miejscu.
Dowód: przechodzące testy golden w obu motywach. Goldeny łapią regresje wizualne, których nikt nie zauważy w diffie. Generuj je na tym samym systemie co CI, bo renderowanie fontów różni się między macOS a Linuksem.
Renderuj stany ładowania, błędu i pustej listy z Riverpoda
Dział zatytułowany „Renderuj stany ładowania, błędu i pustej listy z Riverpoda”Ekrany pokazują pustą stronę podczas ładowania i czerwone pole błędu, gdy API zawodzi, a każdy ekran robi to inaczej.
Dowód: cztery testy stanów dla każdego ekranu. Test „dokładnie jednego pobrania” ma znaczenie, bo Riverpod 3 sam ponawia providery, które zawodzą.
Spraw, żeby ekrany Fluttera wyglądały natywnie na iOS i Androidzie
Dział zatytułowany „Spraw, żeby ekrany Fluttera wyglądały natywnie na iOS i Androidzie”Aplikacja we Flutterze używa na iOS dialogów i przełączników z Material, a użytkownicy iOS to widzą.
Dowód: testy w parach dla iOS i Androida oraz po jednym zrzucie ekranu dialogu i wyboru daty na każdej platformie.
Zachowaj stan dolnej nawigacji dzięki shell routes w go_routerze
Dział zatytułowany „Zachowaj stan dolnej nawigacji dzięki shell routes w go_routerze”Przełączanie zakładek resetuje pozycję przewinięcia i stos nawigacji każdej z nich, a na tablecie dolny pasek wygląda nie na miejscu.
Dowód: test zachowania stanu i dwa testy szerokości.
Przygotuj aplikację React Native lub Flutter do publikacji w sklepach
Dział zatytułowany „Przygotuj aplikację React Native lub Flutter do publikacji w sklepach”Aplikacja ma komplet funkcji, a lista kontrolna wydania istnieje tylko w głowie jednej osoby. Ten przepis zamienia ją w skrypt, który CI uruchamia dla każdego kandydata do wydania.
Dowód: zielony przebieg verify-release.sh i lista kontrolna podpisana przez właściciela wydania. Według strony Android Developers o docelowym poziomie API (sprawdzonej 26 września 2026) Google Play od 31 sierpnia 2026 wymaga, żeby nowe aplikacje i aktualizacje celowały w Androida 16 (API level 36).
Niezależnie od narzędzia, które przygotowuje wydanie, zasada jest ta sama: uruchamiaj verify-release.sh w CI na każdej gałęzi wydania (część iOS na runnerze z macOS), o wyniku decyduje kod wyjścia skryptu, a zanim cokolwiek trafi do sklepu, człowiek podpisuje listę kontrolną. Narzędzia różnią się tylko miejscem przeglądu zmiany. W Claude Code uruchom prompt w trybie planowania (/plan), żeby właściciel wydania zatwierdził listę plików, a przed otwarciem pull requesta uruchom /code-review na gałęzi. W Codeksie zacznij przygotowanie jako zadanie w chmurze, które otwiera pull request ze zmianami konfiguracji i RELEASE_CHECKLIST.md; właściciel wydania zatwierdza tam podbicie wersji i konfigurację podpisywania. W Cursorze przejrzyj zmiany w Info.plist, build.gradle i manifeście prywatności w jednym diffie, zanim je zaakceptujesz; zły versionCode albo pozostawiony entitlement debugowy widać tam od razu.
Jak zweryfikować przepis UI mobilnego bez czytania każdej linijki?
Dział zatytułowany „Jak zweryfikować przepis UI mobilnego bez czytania każdej linijki?”Każdy przepis powyżej kończy się dowodem, który produkuje agent, a ty go sprawdzasz. Dopasuj dowód do rodzaju zmiany:
| Zmiana | Dowód, który ją potwierdza | Kto zatwierdza |
|---|---|---|
| Układ i UI adaptacyjne | Zrzuty ekranu na iOS i Androidzie, telefon i tablet, obie orientacje | Programista, który otworzył zadanie |
| Listy i animacje | Liczba klatek przed i po, z tego samego urządzenia i przewijania; nagranie z fizycznego urządzenia | Programista |
| Stan, nawigacja, deep linki | Testy jednostkowe i widgetów dla każdego stanu i każdego linku, w tym zimnego startu | Recenzent pull requesta |
| Moduły natywne | Czyste buildy natywne na obu platformach i ręczny test na prawdziwym sprzęcie | Programista, na urządzeniu |
| Konfiguracja wydania | Zielony verify-release.sh i podpisana lista kontrolna | Właściciel wydania lub tech lead |
W Claude Code hook sprawdzający typy łapie złe API przy edycji, która je wprowadziła; w Codeksie i Cursorze łapie je bramka npx tsc --noEmit / flutter analyze z AGENTS.md, jeśli agent uruchomi ją przed zakończeniem pracy. Testy i zrzuty ekranu dowodzą zachowania. Umieść to wszystko w pull requeście w formacie pakietu dowodów, a macierze urządzeń i niestabilne testy opisuje strona o wzorcach testowania aplikacji mobilnych.
Co się psuje, gdy agenci piszą UI w React Native i Flutterze?
Dział zatytułowany „Co się psuje, gdy agenci piszą UI w React Native i Flutterze?”- API ze starszej wersji głównej. Agent pisze
estimatedItemSize,Gesture.Pan()alboStateNotifierProvider. Wyjście: trzymaj tabelę wersji wAGENTS.mdi każ agentowi czytać zainstalowane typy, zanim napisze kod biblioteki. W Claude Code hook łapie większość z tych przypadków jako błędy typów; w Codeksie i Cursorze robi to bramka sprawdzania typów zAGENTS.md, jeśli agent ją uruchomi. - Wymyślone lub porzucone pakiety. Agent dodaje pakiet, który nie istnieje, albo taki bez wydania od lat. Wyjście: przed scaleniem sprawdź każdą nową zależność na npm lub pub.dev; zobacz weryfikację zależności.
- API webowe w kodzie mobilnym.
localStorage,window.innerWidthalbodart:htmlw niektórych konfiguracjach się kompilują, a na urządzeniu wywracają aplikację. Wyjście: dopisz je do linii „Forbidden in app code” w blokuAGENTS.mdi odrzucaj każdą zmianę bez zrzutów ekranu z urządzenia. - Nieaktualne binarki natywne. Zmiana natywna wygląda na zepsutą, bo Fast Refresh nie przebudowuje Swifta ani Kotlina. Wyjście: przebuduj binarkę przez
npx expo run:ios/run:android(Expo) albopod install, a potemnpx react-native run-ios/run-android(czysty React Native).npx expo prebuild --cleanniczego nie kompiluje i usuwa bezpośrednie edycje wios/iandroid/. - Sukces tylko na symulatorze. NFC, push i aparat działają tylko na sprzęcie albo wymagają entitlementów, które symulator pomija. Wyjście: wpisz test na urządzeniu do dowodów przepisu i trzymaj pod ręką jeden iPhone i jeden telefon z Androidem.
- Awarie Gradle i CocoaPods. Agent dodaje bibliotekę, która wymaga nowszego Android Gradle Plugin albo wyższego deployment target na iOS. Wyjście: wklej agentowi cały błąd builda i poproś, żeby podał minimalne wersje biblioteki, zanim zmieni pliki builda.
Dokąd dalej z UI mobilnym
Dział zatytułowany „Dokąd dalej z UI mobilnym”- Przegląd rozwoju mobilnego: wybierz stos i zainstaluj jego skille
- Wzorce rozwoju z Expo: routing, buildy EAS i etapowe aktualizacje OTA
- Wzorce rozwoju w React Native: dane offline, wydajność i CI do sklepów
- Wzorce rozwoju we Flutterze: Riverpod, go_router, Dio i polecenie sprawdzające
- Przepisy natywne na iOS i Androida: Swift/SwiftUI i Kotlin/Compose z agentem
- Wzorce testowania aplikacji mobilnych: macierze urządzeń, przepływy Maestro i testy specyficzne dla platform