Why React Native Needs Rules That Prevent Web Patterns
React Native uses React — but it renders native views, not HTML. There are no divs, no spans, no CSS files, no className prop, no media queries, and no DOM. AI assistants trained on React web generate all of these, producing code that doesn't compile. The mental model shift from 'React in a browser' to 'React rendering native views' is one the AI doesn't make without explicit rules.
The most common AI failures: using <div> instead of <View>, <p>/<span> instead of <Text>, className instead of style, CSS files instead of StyleSheet.create(), flexbox with web-specific properties (gap, grid), ScrollView for long lists instead of FlatList, and web navigation (React Router) instead of React Navigation.
These rules target React Native 0.73+ (New Architecture with Fabric renderer). Specify whether you use Expo or bare React Native CLI — the project structure and available APIs differ significantly.
Rule 1: Native Primitives, Not HTML Elements
The rule: 'React Native has no HTML elements. Use View instead of div (a container). Use Text instead of p/span/h1-h6 (all text must be in Text). Use Image instead of img. Use TextInput instead of input. Use Pressable instead of button. Use ScrollView instead of body/overflow. All text — including numbers and strings — must be wrapped in <Text>. Rendering a bare string outside Text crashes the app.'
For text: 'Text components can nest: <Text>Hello <Text style={styles.bold}>world</Text></Text>. Text inherits styles from parent Text (unlike View). Use numberOfLines for truncation: <Text numberOfLines={2}>. Use ellipsizeMode for truncation style: head, middle, tail, clip. There is no CSS text-overflow — use these props.'
For pressables: 'Use Pressable for all tappable elements — not TouchableOpacity (legacy), TouchableHighlight (legacy), or Button (too limited). Pressable supports: onPress, onLongPress, onPressIn, onPressOut, and a style function for pressed state: style={({pressed}) => [styles.button, pressed && styles.pressed]}.'
- View = div container — Text = all text content — Image = img
- TextInput = input — Pressable = button/a — ScrollView = scrollable container
- ALL text in <Text> — bare strings outside Text crash the app
- Pressable for tappable elements — not TouchableOpacity (legacy)
- No HTML elements exist — <div>, <span>, <p>, <h1> don't compile
Every piece of text — strings, numbers, interpolations — MUST be inside a <Text> component. A bare string outside <Text> crashes the app at runtime. AI generates bare strings because web React allows them. React Native does not.
Rule 2: StyleSheet, Not CSS
The rule: 'Use StyleSheet.create() for all styles: const styles = StyleSheet.create({ container: { flex: 1, padding: 16 }, title: { fontSize: 24, fontWeight: "bold" } }). Apply with style prop: <View style={styles.container}>. There are no CSS files, no className, no CSS-in-JS libraries (styled-components doesn't work), no media queries, no pseudo-selectors, no cascading.'
For layout: 'React Native uses Flexbox by default — every View is display: flex. flexDirection defaults to column (not row like web). Use flex: 1 to fill available space. Use alignItems and justifyContent for alignment. There is no CSS Grid. Use gap for spacing between flex children (RN 0.71+). Use Dimensions or useWindowDimensions for responsive layouts.'
For responsive design: 'No media queries — use Dimensions.get("window") or useWindowDimensions hook for screen size. Use Platform.select for platform-specific styles: fontSize: Platform.select({ ios: 16, android: 14 }). Use percentage strings for relative sizing: width: "50%". Use PixelRatio for density-aware sizing.'
React Native's flexDirection defaults to 'column' (not 'row' like web CSS). Every View is display:flex by default. No CSS Grid exists. This trips up every AI generating web-style layouts.
Rule 4: FlatList for All Lists
The rule: 'Use FlatList for all scrollable lists — never ScrollView with .map() for lists longer than ~20 items. FlatList virtualizes: it only renders visible items, recycling off-screen components. Props: data for the array, renderItem for the component, keyExtractor for unique keys. Use SectionList for grouped data with headers.'
For performance: 'Use React.memo on renderItem components to prevent unnecessary re-renders. Use getItemLayout when items have fixed height — it skips measurement. Use initialNumToRender for controlling initial render count. Use maxToRenderPerBatch for controlling batch size. Use windowSize for controlling the render window. Profile with Flipper or React DevTools.'
AI generates ScrollView with items.map() — this renders every item at once, consuming memory and causing jank on long lists. FlatList is the single most important performance pattern in React Native — it's the difference between a smooth 60fps list and a janky, memory-hungry scroll.
ScrollView + .map() renders everything at once — 1000 items = 1000 components in memory. FlatList virtualizes — only visible items render. It's the difference between smooth 60fps scrolling and a frozen app.
Rule 5: Platform-Specific Code
The rule: 'Use Platform.OS for simple platform checks: Platform.OS === "ios" ? iosValue : androidValue. Use Platform.select for style objects: Platform.select({ ios: iosStyles, android: androidStyles }). Use file extensions for platform-specific files: Component.ios.tsx, Component.android.tsx — Metro bundler picks the right one. Use native modules (TurboModules in New Architecture) for platform APIs not exposed by React Native.'
For safe areas: 'Use SafeAreaView from react-native-safe-area-context — not the built-in SafeAreaView (iOS only, inconsistent). Wrap the root of every screen with SafeAreaProvider. Use useSafeAreaInsets() for fine-grained control: const insets = useSafeAreaInsets(); paddingTop: insets.top.'
For platform conventions: 'Follow platform design guidelines: iOS uses flat navigation with tabs, Android uses material design with drawers. Respect platform back button behavior: Android hardware back, iOS swipe-to-go-back. Use platform-specific icons: SF Symbols on iOS, Material Icons on Android.'
Complete React Native Rules Template
Consolidated rules for React Native projects.
- Native primitives: View, Text, Image, Pressable, TextInput — never HTML elements
- StyleSheet.create — no CSS files, no className, no media queries
- Flexbox column-first — Dimensions/useWindowDimensions for responsive — Platform.select for styles
- React Navigation: Stack, Tab, Drawer — typed params — deep linking config
- FlatList for all lists — never ScrollView + map for >20 items — React.memo on renderItem
- Platform.OS / Platform.select / .ios.tsx/.android.tsx for platform code
- SafeAreaView from react-native-safe-area-context — useSafeAreaInsets for control
- Expo or bare CLI — Flipper for debugging — Detox or Maestro for E2E testing