All skills
callstackincubator avatar

/react-native-best-practices

@fa0bad0 official

Provides React Native performance optimization guidelines for FPS, TTI, bundle size, memory leaks, re-renders, and animations. Applies to tasks involving Hermes optimization, JS thread blocking, bridge overhead, FlashList, native modules, or debugging jank and frame drops.

Use this Skill: https://skilld.dev/gh/callstackincubator/agent-skills/react-native-best-practices

This session only. Nothing lands on disk.

referencesnative-sdks-over-polyfills.md

≈1.6k tokens on demand. Your agent reads this file only when SKILL.md points to it.

Skill: Native SDKs

Replace web polyfills and JS navigators with native React Native implementations for better performance.

Quick Pattern

Before (JS polyfills - 430+ KB):

import '@formatjs/intl-datetimeformat/polyfill';
import CryptoJS from 'crypto-js';
import { createStackNavigator } from '@react-navigation/stack';

After (native implementations):

// Keep this polyfill only if the app uses DateTimeFormat options/locales
// unsupported by the target Hermes/platform combination.
import { createHash } from 'react-native-quick-crypto';
import { createNativeStackNavigator } from '@react-navigation/native-stack';

When to Use

  • Large JS bundle from polyfills
  • Navigation feels non-native
  • Crypto operations are slow
  • Internationalization bloating bundle

Step-by-Step Instructions

1. Remove Unnecessary Intl Polyfills

Hermes supports many Intl APIs natively, but not every constructor and method combination across platforms. Audit the exact APIs and methods you use before removing polyfills:

// BEFORE: All these polyfills (430+ KB)
import '@formatjs/intl-getcanonicallocales/polyfill';
import '@formatjs/intl-locale/polyfill';
import '@formatjs/intl-numberformat/polyfill';
import '@formatjs/intl-numberformat/locale-data/en';
import '@formatjs/intl-datetimeformat/polyfill';
import '@formatjs/intl-datetimeformat/locale-data/en';
import '@formatjs/intl-pluralrules/polyfill';
import '@formatjs/intl-pluralrules/locale-data/en';
import '@formatjs/intl-relativetimeformat/polyfill';
import '@formatjs/intl-relativetimeformat/locale-data/en';
import '@formatjs/intl-displaynames/polyfill';

Hermes Intl support must be checked against the Hermes version in the app:

API Hermes Keep Polyfill?
Intl.Collator ✅ No
Intl.DateTimeFormat ⚠️ Partial Maybe
Intl.NumberFormat ⚠️ Partial Maybe
Intl.getCanonicalLocales() ✅ No
Intl.supportedValuesOf() ✅ No
Intl.Locale ❌ Yes
Intl.PluralRules ❌ Yes
Intl.RelativeTimeFormat ❌ Yes
Intl.DisplayNames ❌ Yes
Intl.ListFormat ❌ Yes
Intl.Segmenter ❌ Yes

Constructor support does not guarantee every option or method your app uses. Keep polyfills for any API, option, locale data, or method the app depends on but Hermes does not fully support on the target platform.

// AFTER: Keep only the polyfills your app still needs
import '@formatjs/intl-locale/polyfill';
import '@formatjs/intl-pluralrules/polyfill';
import '@formatjs/intl-pluralrules/locale-data/en';
import '@formatjs/intl-relativetimeformat/polyfill';
import '@formatjs/intl-relativetimeformat/locale-data/en';
import '@formatjs/intl-displaynames/polyfill';

If you use Intl.NumberFormat.prototype.formatToParts() on Hermes/iOS, also keep:

import '@formatjs/intl-numberformat/polyfill';
import '@formatjs/intl-numberformat/locale-data/en';

2. Use Native Crypto

Replace JS crypto with native C++ implementation:

npm install react-native-quick-crypto
// BEFORE: Slow JS implementation
import CryptoJS from 'crypto-js';

// AFTER: Native C++ implementation
import { createHash } from 'react-native-quick-crypto';

Essential for:

  • Web3 wallet seed generation
  • CSPRNG (Cryptographically Secure Random Numbers)
  • Any heavy cryptographic operations

Benchmark crypto changes on the target device class. Native implementations usually reduce JS-thread work, but the exact win depends on algorithm, payload size, and bridge/JSI overhead.

3. Use Native Stack Navigator

npm install @react-navigation/native-stack react-native-screens
// BEFORE: JS-based stack (more flexible, less native)
import { createStackNavigator } from '@react-navigation/stack';
const Stack = createStackNavigator();

// AFTER: Native stack (native feel, better performance)
import { createNativeStackNavigator } from '@react-navigation/native-stack';
const Stack = createNativeStackNavigator();

// Usage is nearly identical
<Stack.Navigator>
  <Stack.Screen name="Home" component={HomeScreen} />
  <Stack.Screen name="Details" component={DetailsScreen} />
</Stack.Navigator>

Benefits:

  • Native navigation animations
  • Platform-specific headers (large titles on iOS)
  • Lower memory usage
  • Offloads work from JS thread

4. Use Native Bottom Tabs

npm install @bottom-tabs/react-navigation react-native-bottom-tabs
// BEFORE: JS tabs
import { createBottomTabNavigator } from '@react-navigation/bottom-tabs';
const Tabs = createBottomTabNavigator();

// AFTER: Native tabs
import { createNativeBottomTabNavigator } from '@bottom-tabs/react-navigation';
const Tabs = createNativeBottomTabNavigator();

<Tabs.Navigator>
  <Tabs.Screen name="Home" component={HomeScreen} />
  <Tabs.Screen name="Profile" component={ProfileScreen} />
</Tabs.Navigator>

Recommended Native Libraries

Category Library Description
Navigation react-native-screens Native screen containers
Menus zeego Native menus (Radix-like API)
Slider @react-native-community/slider Native slider
Date Picker react-native-date-picker Native date/time picker

Decision Matrix

Scenario Use Native? Tradeoff
Standard navigation ✅ Yes Slight API differences
Custom transition animations ⚠️ Maybe Native is more limited
Platform-consistent UI ✅ Yes Less customization
Unique/branded design ⚠️ Consider JS Native may not support

Common Pitfalls

  • Assuming constructor support means full method coverage: Check the specific Hermes API and methods you call
  • Ignoring migration effort: Native navigators have slightly different APIs
  • Over-customizing native components: If design requires heavy customization, JS might be better

Related Skills

Source: SKILL.md on GitHub

1 alert17d5 checks · Risk SAFE
  • Gen Agent Trust Hub17d

    This skill provides a comprehensive performance optimization guide for React Native applications. It contains standard developer workflows using command-line tools and patterns for advanced techniques like remote code splitting, which include detailed security hardening advice.

  • Socket17d

    No alerts

  • Snyk17d

    Risk: LOW · No issues

  • Runlayer7mo

    11/31 files flagged

  • ZeroLeaks5mo

    Score: 93/100 · 2 sections analyzed

Signed by skilld at fa0bad0. This ties the file your Agent reads to that commit on GitHub. It does not review the instructions.

Last checked against GitHub 2 weeks ago.

Activeupdated 2 months ago
  • Performance
  • react-native
  • optimization
  • profiling
  • fps
  • bundle-size
  • memory
  • hermes
  • flatlist
  • animations

README badge

README badge for callstackincubator/agent-skills/react-native-best-practices

Provides React Native performance optimization guidelines covering FPS, TTI, bundle size, memory leaks, re-renders, and animations. Includes reference documentation for Hermes, FlashList, Turbo Modules, React Compiler, Reanimated, and profiling with Xcode and Android Studio.

Generated from the current SKILL.md.

Does this skill cover Expo apps?
Yes. The guidelines apply to both bare React Native and Expo projects. Expo SDK 52+ supports tree shaking and Re.Pack code splitting.
What performance metrics should I measure first?
Start with FPS (use React Native DevTools), Time To Interactive (TTI), bundle size, and memory growth. The skill emphasizes measuring baseline metrics before and after optimization to validate improvements.
Does this cover Hermes optimization?
Yes. The skill includes Hermes-specific guidance such as disabling JS bundle compression on Android to enable mmap, and checking Hermes API coverage before removing polyfills.
What if I'm using a list library other than FlatList or FlashList?
The skill prioritizes FlatList and FlashList as virtualized replacements for ScrollView. It includes library version checks (e.g., FlashList v2 API changes) but focuses on these two libraries.
Does this include native profiling guidance?
Yes. The skill covers profiling with Xcode Instruments (iOS) and Android Studio CPU Profiler, plus guidance on native threading, Turbo Modules, and C++ performance-critical code.

Generated from the current SKILL.md. These answers refresh after source changes.