react-native-best-practices
SKILL.md
React Native Best Practices
Performance optimization guide for React Native applications based on Callstack's "Ultimate Guide to React Native Optimization".
When to Apply
Reference these guidelines when:
- Debugging slow/janky UI or animations
- Investigating memory leaks (JS or native)
- Optimizing app startup time (TTI)
- Reducing bundle or app size
- Writing native modules (Turbo Modules)
- Profiling React Native performance
Priority-Ordered Guidelines
| Priority | Category | Impact | Prefix |
|---|---|---|---|
| 1 | FPS & Re-renders | CRITICAL | js-* |
| 2 | Bundle Size | CRITICAL | bundle-* |
| 3 | TTI Optimization | HIGH | native-*, bundle-* |
| 4 | Native Performance | HIGH | native-* |
| 5 | Memory Management | MEDIUM-HIGH | js-*, native-* |
| 6 | Animations | MEDIUM | js-* |
Quick Reference
Critical: FPS & Re-renders
Profile first:
# Open React Native DevTools
# Press 'j' in Metro, or shake device → "Open DevTools"
Common fixes:
- Replace ScrollView with FlatList/FlashList for lists
- Use React Compiler for automatic memoization
- Use atomic state (Jotai/Zustand) to reduce re-renders
- Use
useDeferredValuefor expensive computations
Critical: Bundle Size
Analyze bundle:
npx react-native bundle \
--entry-file index.js \
--bundle-output output.js \
--platform ios \
--sourcemap-output output.js.map \
--dev false --minify true
npx source-map-explorer output.js --no-border-checks
Common fixes:
- Avoid barrel imports (import directly from source)
- Remove unnecessary Intl polyfills (Hermes has native support)
- Enable tree shaking (Expo SDK 52+ or Re.Pack)
- Enable R8 for Android native code shrinking
High: TTI Optimization
Measure TTI:
- Use
react-native-performancefor markers - Only measure cold starts (exclude warm/hot/prewarm)
Common fixes:
- Disable JS bundle compression on Android (enables Hermes mmap)
- Use native navigation (react-native-screens)
- Defer non-critical work with
InteractionManager
High: Native Performance
Profile native:
- iOS: Xcode Instruments → Time Profiler
- Android: Android Studio → CPU Profiler
Common fixes:
- Use background threads for heavy native work
- Prefer async over sync Turbo Module methods
- Use C++ for cross-platform performance-critical code
Problem → Solution Mapping
| Problem | Start With |
|---|---|
| App feels slow/janky | Measure FPS → Profile React |
| Too many re-renders | Profile React → React Compiler |
| Slow startup (TTI) | Measure TTI → Analyze bundle |
| Large app size | Analyze app → Enable R8 |
| Memory growing | Check JS or native memory leaks |
| Animation drops frames | Use Reanimated worklets |
| List scroll jank | Use FlatList/FlashList |
| TextInput lag | Use uncontrolled components |
| Native module slow | Turbo Modules → Threading |
Key Patterns
Use FlashList for Large Lists
// Bad: ScrollView with many items
<ScrollView>
{items.map(item => <Item key={item.id} {...item} />)}
</ScrollView>
// Good: FlashList with virtualization
import { FlashList } from "@shopify/flash-list";
<FlashList
data={items}
renderItem={({ item }) => <Item {...item} />}
estimatedItemSize={100}
/>
Avoid Barrel Imports
// Bad: imports entire barrel
import { Button, Card, Modal } from '@/components';
// Good: direct imports
import { Button } from '@/components/Button';
import { Card } from '@/components/Card';
Use Reanimated for Smooth Animations
import Animated, {
useAnimatedStyle,
withSpring
} from 'react-native-reanimated';
const animatedStyle = useAnimatedStyle(() => ({
transform: [{ scale: withSpring(pressed.value ? 0.9 : 1) }],
}));
Defer Non-Critical Work
import { InteractionManager } from 'react-native';
useEffect(() => {
InteractionManager.runAfterInteractions(() => {
// Expensive work after animations complete
loadAnalytics();
});
}, []);
Attribution
Based on "The Ultimate Guide to React Native Optimization" by Callstack - 642+ installs.
Weekly Installs
3
Repository
5dlabs/ctoFirst Seen
Jan 24, 2026
Installed on
claude-code2
windsurf1
trae1
opencode1
codex1
antigravity1