---
name: "React Native"
description: "Always-on rules for writing React Native and Expo screens, components and hooks in TypeScript."
applyTo: "**/*.tsx,**/*.ts"
---

> In React Native repositories this file replaces the web React instructions; both match `.tsx` files.

# React Native rules

Follow the existing project conventions first; these rules apply to new and changed code.

## Platform and structure

- Default to Expo (managed workflow, dev client, config plugins) and Expo SDK modules before community libraries. They support the New Architecture.
- Never edit `ios/` or `android/` in a managed app; change native config through `app.json` and config plugins.
- No DOM or web APIs: no `div`, `window`, `document`, `localStorage` or CSS files. They do not exist on device.
- Wrap every string in `<Text>`; a bare string inside `View` crashes.
- Keep route files in `app/` thin: they render a screen from `features/<feature>/`. No business logic in routes or `_layout.tsx`.
- Use `Platform.select` for small differences and `.ios.tsx`/`.android.tsx` files only for real divergence.
- Handle Android back and iOS swipe-back; intercept back only for unsaved changes.

## Styling and layout

- Use `StyleSheet.create` at the bottom of the file with values from theme tokens; no magic numbers or hard-coded colours.
- Support light and dark mode through the theme hook and `useColorScheme()`.
- Apply safe areas with `useSafeAreaInsets()` as padding; do not nest `SafeAreaView` inside navigators. It double-pads.
- Use `useWindowDimensions()`, never `Dimensions.get` at module scope. Breaks rotation and foldables.
- Handle the keyboard with `KeyboardAvoidingView` or a keyboard controller, and `keyboardShouldPersistTaps="handled"` on scroll views.
- Use `expo-image` with explicit dimensions for images.

## Lists and rendering

- Render data lists with `FlashList` (or `FlatList`), never `ScrollView` plus `.map()`. Only visible rows are rendered.
- Provide a stable `keyExtractor`, an empty state, and pull-to-refresh and pagination where the data needs them.
- Never nest same-direction scroll views; use list header and footer components.
- Memoise row components and pass primitives or stable objects; no inline closures or formatting inside rows.
- Keep state low in the tree and split contexts before reaching for `memo`; each re-render costs JS-thread time.
- Animate with Reanimated and gestures with Gesture Handler; never `setState` per frame or `PanResponder`.

## Navigation

- Use the project's router (Expo Router or React Navigation) with typed route params; parse and validate params before use.
- Use `router.replace` after login or completion and `router.push` for drill-down.
- Gate auth in the root layout with a redirect; do not render different stacks conditionally.
- Make every screen deep-linkable and handle a missing entity with a designed not-found state.

## Data, storage and security

- Fetch through the shared API client and query hooks, with timeouts and cancellation on unmount.
- Render loading, empty, error (with retry) and offline states; never fail silently without a network.
- Persist the query cache and queue offline mutations, or show a clear "will sync when online" state.
- Store tokens and secrets in `expo-secure-store` only; never in AsyncStorage, MMKV or persisted state. Those are not encrypted.
- Never ship API secrets in the bundle; `EXPO_PUBLIC_` variables are public.
- Request permissions at the moment of use with an explanation, and handle denied with a path to settings.

## Accessibility and tests

- Use `Pressable` for anything tappable, with `accessibilityRole`, `accessibilityLabel` and `accessibilityState`; no `TouchableOpacity` in new code.
- Make touch targets at least 44×44 pt (use `hitSlop`) and support dynamic type up to 200%.
- Keep TypeScript `strict`; no `any` and no non-null `!` to silence errors.
- Test behaviour with React Native Testing Library, querying by role, label and text, not test ids or implementation details.
- Mock the network, not your hooks; avoid snapshot tests. They break on every style change and prove little.

Go deeper: for larger tasks use the react-native-development, react-native-architecture and react-native-performance skills, and frontend-code-review before opening a pull request.
