dist/plugins/mobile-framework-react-native/skills/mobile-framework-react-native/SKILL.md
React Native mobile development patterns - New Architecture (Fabric, TurboModules, JSI), component architecture, React Navigation 7+, FlashList v2 optimization, gestures with Reanimated 4, platform-specific code, React 19 features
npx skillsauth add agents-inc/skills mobile-framework-react-nativeInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Quick Guide: Build cross-platform mobile apps with React Native's New Architecture (default since 0.76). Use FlashList for performant lists (or FlatList with proper optimization). Use type-safe navigation hooks with static or dynamic API. Keep components small, memoize callbacks passed to lists, and test on both platforms from day one.
<critical_requirements>
All code must follow project conventions in CLAUDE.md (kebab-case, named exports, import ordering,
import type, named constants)
(You MUST use FlashList (preferred) or FlatList for lists with more than 20 items - NEVER ScrollView with .map() for long lists)
(You MUST memoize renderItem callbacks and use stable keyExtractor functions - avoid key props on FlashList items as it breaks recycling)
(You MUST use react-native-safe-area-context for safe areas - React Native's built-in SafeAreaView is deprecated in 0.81+ and will be removed)
(You MUST test on BOTH iOS AND Android from day one - platform differences cause bugs)
(You MUST use Platform.select() or platform-specific files for platform differences - shadows, fonts, and feedback differ)
(You MUST be aware the New Architecture is enabled by default since React Native 0.76 - Fabric, TurboModules, and bridgeless mode)
</critical_requirements>
Auto-detection: React Native, react-native, React Navigation, @react-navigation, StyleSheet, FlatList, FlashList, ScrollView, View, Text, Pressable, TouchableOpacity, Platform.OS, Platform.select, SafeAreaView, KeyboardAvoidingView, Reanimated, Gesture Handler, TurboModules, Fabric, JSI, New Architecture
When to use:
Key patterns covered:
use, ref as propsWhen NOT to use:
Detailed Resources:
React Native enables building native mobile apps using React patterns. The key insight is that mobile has different constraints than web: performance matters more, platform conventions differ, and users expect native feel.
Core principles:
New Architecture (React Native 0.76+):
The New Architecture removes the legacy bridge and provides:
Performance improvements with New Architecture: ~15ms faster app startup (~8% improvement), ~3.8MB smaller app size (20% reduction), ~15x faster Metro resolver, ~4x faster warm builds.
Mental model:
React Native is NOT "write once, run anywhere" - it's "learn once, write anywhere." Expect to write some platform-specific code. The shared codebase is typically 80-95%, not 100%.
</philosophy>Build components with TypeScript, accessibility props, and platform awareness. Key concerns: use Pressable over TouchableOpacity, include accessibilityRole/accessibilityState, use testID for E2E tests, and memoize styles with useMemo.
// Key pattern: accessibility + testID + memoized styles
<Pressable
ref={ref}
style={buttonStyle}
onPress={handlePress}
disabled={disabled}
testID={testID}
accessibilityRole="button"
accessibilityState={{ disabled }}
>
<Text style={styles.text}>{children}</Text>
</Pressable>
Why good: accessibilityRole/State for screen readers, testID for E2E, Pressable supports android_ripple unlike TouchableOpacity
See examples/core.md for full component with forwardRef, variants, and loading state.
Handle device notches, status bars, and keyboard properly. Use react-native-safe-area-context (RN's built-in SafeAreaView is deprecated in 0.81+).
import { SafeAreaView, useSafeAreaInsets } from "react-native-safe-area-context";
// Screen wrapper with safe areas
<SafeAreaView style={{ flex: 1 }} edges={["top", "bottom"]}>
{children}
</SafeAreaView>
// Keyboard handling for forms
<KeyboardAvoidingView
style={{ flex: 1 }}
behavior={Platform.OS === "ios" ? "padding" : "height"}
keyboardVerticalOffset={Platform.select({ ios: HEADER_HEIGHT, android: 0 })}
>
<ScrollView keyboardShouldPersistTaps="handled">
<FormContent />
</ScrollView>
</KeyboardAvoidingView>
Why good: SafeAreaView handles notches/Dynamic Island, KeyboardAvoidingView prevents keyboard overlap, Platform.select handles iOS/Android differences
Handle iOS and Android differences with Platform.select for small differences, separate files (.ios.tsx/.android.tsx) for significant divergence.
// Platform.select for shadows (iOS shadow props ignored on Android)
const styles = StyleSheet.create({
card: {
...Platform.select({
ios: {
shadowColor: "#000",
shadowOffset: { width: 0, height: 2 },
shadowOpacity: 0.1,
shadowRadius: 4,
},
android: { elevation: 4 },
}),
},
text: {
fontWeight: Platform.select({ ios: "600", android: "bold" }),
},
});
Why good: iOS shadow props are completely ignored on Android, fontWeight 100-900 unreliable on Android
For platform-specific file splitting with haptics, see examples/core.md.
Use FlashList for performant lists (cell recycling, 50% less blank area). FlashList v2 is New Architecture only. Always memoize renderItem and keyExtractor. Never add key props to FlashList items (breaks recycling).
// Critical: memoized renderItem + no key prop on items
const renderItem = useCallback(
({ item }: { item: Product }) => (
<ProductItem item={item} onPress={onProductPress} />
),
[onProductPress]
);
<FlashList
data={products}
renderItem={renderItem}
estimatedItemSize={ITEM_HEIGHT} // Optional in v2, required in v1
getItemType={(item) => item.category} // Improves recycling pool
/>
Why good: useCallback prevents renderItem recreation, getItemType optimizes recycling, no key prop preserves FlashList's main benefit
See examples/performance.md for full FlashList and FlatList optimization patterns.
React Native 0.78+ includes React 19 with new hooks and simplified patterns.
import { useOptimistic } from "react";
// useOptimistic - optimistic UI updates with automatic rollback
const [optimisticMessages, addOptimisticMessage] = useOptimistic(
messages,
(state, newMessage: Message) => [...state, { ...newMessage, sending: true }]
);
// ref as props - no more forwardRef wrapper needed (React 19)
function Input({ ref, placeholder, onChangeText }: InputProps) {
return <TextInput ref={ref} placeholder={placeholder} onChangeText={onChangeText} />;
}
Why good: useOptimistic provides automatic rollback on errors, ref as props eliminates forwardRef boilerplate
</patterns><red_flags>
High Priority Issues:
Medium Priority Issues:
Gotchas & Edge Cases:
<Text> component - raw strings cause crashes</red_flags>
<critical_reminders>
All code must follow project conventions in CLAUDE.md
(You MUST use FlashList (preferred) or FlatList for lists with more than 20 items - NEVER ScrollView with .map() for long lists)
(You MUST memoize renderItem callbacks and use stable keyExtractor functions - avoid key props on FlashList items as it breaks recycling)
(You MUST use react-native-safe-area-context for safe areas - React Native's built-in SafeAreaView is deprecated in 0.81+ and will be removed)
(You MUST test on BOTH iOS AND Android from day one - platform differences cause bugs)
(You MUST use Platform.select() or platform-specific files for platform differences - shadows, fonts, and feedback differ)
(You MUST be aware the New Architecture is enabled by default since React Native 0.76 - Fabric, TurboModules, and bridgeless mode)
Failure to follow these rules will result in poor performance, platform-specific bugs, and broken UX on mobile devices.
</critical_reminders>
development
Material Design component library for Vue 3
development
VitePress 1.x — Vue-powered static site generator for documentation sites, built on Vite
tools
Docusaurus 3.x documentation framework — site configuration, docs/blog plugins, sidebars, versioning, MDX, swizzling, and deployment
development
TanStack Form patterns - useForm, form.Field, validators, arrays, linked fields, createFormHook, type safety