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-memory-leaks.md

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

Skill: Hunt Native Memory Leaks

Find native memory leaks using Xcode Leaks and Android Studio Memory Profiler.

Quick Command

# iOS: Profile with Leaks instrument
# Xcode → Product → Profile (Cmd+I) → Leaks template

# Android: Memory Profiler
# Android Studio → Run → Profile → Track Memory Consumption

When to Use

  • App memory grows despite JS profiler showing no leaks
  • Native modules suspected of leaking
  • Activity recreation causes memory growth (Android)
  • C++/Swift/Kotlin code under investigation

iOS: Xcode Leaks

Quick Check: Memory Report

  1. Run app via Xcode
  2. Open Debug Navigator (side panel)
  3. Click Memory
  4. Watch graph for continuous growth

Deep Analysis: Instruments Leaks

Xcode Instruments Templates

  1. Xcode → Product → Profile (or Cmd+I)
  2. Select Leaks template (highlighted with orange triangle icon in the grid)
  3. Click Choose
  4. Click Record (red circle)
  5. Use the app, perform suspect actions
  6. Stop recording

Analyzing Results

Red markers = Leaked memory detected

Click on leak to see:

  • Leaked Object: Type and size
  • Responsible Library: Which code leaked
  • Responsible Frame: Exact function
  • Stack Trace: Full call path (right panel)

Open the responsible frame to jump to source when symbols are available.

Common Native Leak: Missing Ownership

void createNewStrings() {
    auto str = std::make_unique<std::string>("Hello");
}

Prefer RAII/smart pointers over raw new/delete in native module code.

Android: Memory Profiler

Launch Profiler

Use Android Studio Memory Profiler and select a memory-consumption recording for the target process.

Recording

  1. Start the app
  2. Perform actions that might leak
  3. Watch memory graph for growth patterns

Analyzing Allocations

Memory profiler shows:

  • Allocations count: Objects created
  • Deallocations count: Objects freed
  • Live objects: Still in memory

If allocations greatly exceed deallocations after GC and after repeating the same flow, suspect a leak; confirm via retained objects, references, and lifecycle expectations.

LeakCanary (Android JVM Leaks)

Use LeakCanary as a debug-only first line of defense for Android JVM leaks such as retained Activity/Context references, listeners, and coroutines that outlive a module. It does not see JS heap leaks or JSI/C++ Turbo Module leaks and can report React Native framework false positives.

Common Android Leak: Listener Not Removed

// BAD: Leaks MainActivity on config change
class MainActivity : AppCompatActivity(), Callback {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        EventManager.addListener(this)
        // Never removed!
    }
}

// GOOD: Remove listener
class MainActivity : AppCompatActivity(), Callback {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        EventManager.addListener(this)
    }
    
    override fun onDestroy() {
        EventManager.removeListener(this)
        super.onDestroy()
    }
}

Activity Recreation Test

Repeat navigation and configuration-change flows, then check whether old activities or module instances are retained after GC.

React Native note: RN opts out via android:configChanges in manifest, but native code might not.

Use agent-device to repeat rotation/navigation scenarios, capture snapshots/screenshots, and collect device evidence. If it is missing and device verification is needed, install it through the environment's approved/trusted path or ask the user to install or enable it. Read the agent-device skill or CLI help when available before writing exact commands.

Debugging Workflow

iOS

  1. Profile with Instruments Leaks
  2. Trigger suspect actions repeatedly
  3. Wait for red leak markers
  4. Click to identify responsible frame
  5. Fix and re-test

Android

  1. Profile memory consumption
  2. Trigger suspect actions (rotate, navigate)
  3. Check allocation/deallocation counts
  4. Look for classes with 0 deallocations
  5. Fix and re-test

Code Fixes by Pattern

Reference Cycle (Swift)

// BAD
class Parent {
    var child: Child?
}
class Child {
    var parent: Parent?  // Strong reference cycle
}

// GOOD
class Parent {
    var child: Child?
}
class Child {
    weak var parent: Parent?  // Weak breaks cycle
}

Missing Cleanup (C++)

// BAD
void process() {
    auto* data = new LargeData();
    if (error) return;  // Leak!
    delete data;
}

// GOOD: RAII with unique_ptr
void process() {
    auto data = std::make_unique<LargeData>();
    if (error) return;  // Automatically cleaned up
}

Verification

After fixing:

  1. Re-run profiler
  2. Perform same actions
  3. Verify:
    • iOS: No red leak markers
    • Android: Allocations return to a stable baseline after GC and repeated flows

Common Pitfalls

  • Testing in debug mode: Some leaks only appear in release
  • Not waiting for GC: Force GC before concluding no leak
  • Ignoring small leaks: They add up over time
  • Missing cleanup in invalidate(): Turbo Modules need proper cleanup

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.