← Building React Native AppsCONTENT HISTORY

Update to Building React Native Apps

Snapshot Sep 30, 2026 · 23:14 UTC · version 0.2.0

Collection source: not recorded for this historical snapshot.

WHAT CHANGED · RULE-BASED ANALYSIS

First saved snapshot

No earlier snapshot is available to establish a change.

Compare saved observations

Download comparison JSON
Full technical diff · 0 changed fields
Full snapshot data
{
  "name": "react-native-best-practices",
  "description": "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.",
  "included_files": [
    {
      "relative_path": "POWER.md",
      "size_in_bytes": 8312
    },
    {
      "relative_path": "agents/openai.yaml",
      "size_in_bytes": 227
    },
    {
      "relative_path": "references/bundle-analyze-app.md",
      "size_in_bytes": 5461
    },
    {
      "relative_path": "references/bundle-analyze-js.md",
      "size_in_bytes": 7029
    },
    {
      "relative_path": "references/bundle-barrel-exports.md",
      "size_in_bytes": 5406
    },
    {
      "relative_path": "references/bundle-code-splitting.md",
      "size_in_bytes": 7545
    },
    {
      "relative_path": "references/bundle-hermes-mmap.md",
      "size_in_bytes": 4133
    },
    {
      "relative_path": "references/bundle-library-size.md",
      "size_in_bytes": 4150
    },
    {
      "relative_path": "references/bundle-native-assets.md",
      "size_in_bytes": 5041
    },
    {
      "relative_path": "references/bundle-r8-android.md",
      "size_in_bytes": 5356
    },
    {
      "relative_path": "references/bundle-tree-shaking.md",
      "size_in_bytes": 5690
    },
    {
      "relative_path": "references/images/bundle-treemap-source-map-explorer.png",
      "size_in_bytes": 667493
    },
    {
      "relative_path": "references/images/controlled-textinput-pingpong.png",
      "size_in_bytes": 127223
    },
    {
      "relative_path": "references/images/devtools-flamegraph.png",
      "size_in_bytes": 520655
    },
    {
      "relative_path": "references/images/emerge-xray-ios.png",
      "size_in_bytes": 439669
    },
    {
      "relative_path": "references/images/expo-atlas-treemap.png",
      "size_in_bytes": 618904
    },
    {
      "relative_path": "references/images/flashlight-flatlist-vs-flashlist.png",
      "size_in_bytes": 313215
    },
    {
      "relative_path": "references/images/fps-drop-graph.png",
      "size_in_bytes": 152493
    },
    {
      "relative_path": "references/images/memory-heap-snapshot.png",
      "size_in_bytes": 308032
    },
    {
      "relative_path": "references/images/tti-warm-start-diagram.png",
      "size_in_bytes": 127254
    },
    {
      "relative_path": "references/images/view-hierarchy-flattening.png",
      "size_in_bytes": 2587021
    },
    {
      "relative_path": "references/images/xcode-instruments-templates.png",
      "size_in_bytes": 408360
    },
    {
      "relative_path": "references/images/xcode-thread-view.png",
      "size_in_bytes": 178440
    },
    {
      "relative_path": "references/js-animations-reanimated.md",
      "size_in_bytes": 8015
    },
    {
      "relative_path": "references/js-atomic-state.md",
      "size_in_bytes": 5267
    },
    {
      "relative_path": "references/js-bottomsheet.md",
      "size_in_bytes": 12199
    },
    {
      "relative_path": "references/js-concurrent-react.md",
      "size_in_bytes": 6652
    },
    {
      "relative_path": "references/js-lists-flatlist-flashlist.md",
      "size_in_bytes": 5998
    },
    {
      "relative_path": "references/js-measure-fps.md",
      "size_in_bytes": 5306
    },
    {
      "relative_path": "references/js-memory-leaks.md",
      "size_in_bytes": 5301
    },
    {
      "relative_path": "references/js-profile-react.md",
      "size_in_bytes": 5871
    },
    {
      "relative_path": "references/js-react-compiler.md",
      "size_in_bytes": 7372
    },
    {
      "relative_path": "references/js-uncontrolled-components.md",
      "size_in_bytes": 5492
    },
    {
      "relative_path": "references/native-android-16kb-alignment.md",
      "size_in_bytes": 3761
    },
    {
      "relative_path": "references/native-measure-tti.md",
      "size_in_bytes": 6527
    },
    {
      "relative_path": "references/native-memory-leaks.md",
      "size_in_bytes": 5627
    },
    {
      "relative_path": "references/native-memory-patterns.md",
      "size_in_bytes": 5986
    },
    {
      "relative_path": "references/native-platform-setup.md",
      "size_in_bytes": 3786
    },
    {
      "relative_path": "references/native-profiling.md",
      "size_in_bytes": 4358
    },
    {
      "relative_path": "references/native-sdks-over-polyfills.md",
      "size_in_bytes": 6279
    },
    {
      "relative_path": "references/native-threading-model.md",
      "size_in_bytes": 6882
    },
    {
      "relative_path": "references/native-turbo-modules.md",
      "size_in_bytes": 5650
    },
    {
      "relative_path": "references/native-view-flattening.md",
      "size_in_bytes": 5236
    }
  ],
  "skill_md_contents": "---\nname: react-native-best-practices\ndescription: 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.\nlicense: MIT\n---\n\n# React Native Best Practices\n\n## Overview\n\nPerformance optimization guide for React Native applications, covering JavaScript/React, Native (iOS/Android), and bundling optimizations. Based on Callstack's \"Ultimate Guide to React Native Optimization\".\n\n## When to Apply\n\nReference these guidelines when:\n- Debugging slow/janky UI or animations\n- Investigating memory leaks (JS or native)\n- Optimizing app startup time (TTI)\n- Reducing bundle or app size\n- Writing native modules (Turbo Modules)\n- Profiling React Native performance\n- Reviewing React Native code for performance\n\n## Security Notes\n\n- Treat shell commands in these references as local developer operations. Review them before running, prefer version-pinned tooling, and avoid piping remote scripts directly to a shell.\n- Treat third-party libraries and plugins as dependencies that still require normal supply-chain controls: pin versions, verify provenance, and update through your standard review process.\n- Treat remote chunk loading as first-party artifact delivery only. Prefer app-bundled chunks or signed CI release manifests; hosted chunks must come from trusted HTTPS origins you control and be pinned to the current app release.\n\n## Priority-Ordered Guidelines\n\n| Priority | Category | Impact | Prefix |\n|----------|----------|--------|--------|\n| 1 | FPS & Re-renders | CRITICAL | `js-*` |\n| 2 | Bundle Size | CRITICAL | `bundle-*` |\n| 3 | TTI Optimization | HIGH | `native-*`, `bundle-*` |\n| 4 | Native Performance | HIGH | `native-*` |\n| 5 | Memory Management | MEDIUM-HIGH | `js-*`, `native-*` |\n| 6 | Animations | MEDIUM | `js-*` |\n\nImpact labels are triage hints: CRITICAL first, HIGH next, MEDIUM when evidence points there.\n\n## Quick Reference\n\n### Optimization Workflow\n\nFollow this cycle for any performance issue: **Measure → Optimize → Re-measure → Validate**\n\n1. **Measure**: Capture baseline metrics before changes. For runtime issues, prefer commit timeline, re-render counts, slow components, heaviest-commit breakdown, and startup/TTI when available. Component tree depth or count are optional context, not substitutes. Do not recommend memoization, atomic state, or compiler changes without a measured render or FPS problem.\n2. **Optimize**: Apply the targeted fix from the relevant reference\n3. **Re-measure**: Run the same measurement to get updated metrics\n4. **Validate**: Confirm improvement (e.g., FPS 45→60, TTI 3.2s→1.8s, bundle 2.1MB→1.6MB)\n\nIf metrics did not improve, revert and try the next suggested fix.\n\n### Review Guardrails\n\n- Check library versions before suggesting API-specific fixes. Example: FlashList v2 deprecates `estimatedItemSize`, so do not flag it as missing there.\n- Do not suggest `useMemo` or `useCallback` dependency changes unless behavior is demonstrably incorrect or profiling shows wasted work tied to that value.\n- Do not report stale closures speculatively. Show the stale read path, a repro, or profiler evidence before calling it out.\n- When profiling a flow, measure the target interaction itself. Do not treat component tree depth or component count as the main performance evidence.\n\n### Critical: FPS & Re-renders\n\n**Profile first:**\n```bash\nagent-device react-devtools status\nagent-device react-devtools wait --connected\nagent-device react-devtools profile start\nagent-device react-devtools profile stop\nagent-device react-devtools profile slow --limit 5\nagent-device react-devtools profile rerenders --limit 5\nagent-device react-devtools profile timeline --limit 20\n```\n\nDrive the target interaction with normal `agent-device` commands between `profile start` and `profile stop`.\n\nManual fallback when `agent-device` is unavailable: open React Native DevTools from Metro (`j`) or the Dev Menu, use the Profiler tab, and record the same interaction.\n\nFor release-build React component profiling, connect [`@callstack/inspector`](https://github.com/callstackincubator/inspector#inspector) first so React DevTools can attach to the release app, then run the `agent-device react-devtools` flow above.\n\n**Common fixes:**\n- Replace ScrollView with FlatList/FlashList/Legend List for long lists\n- After profiling shows cascading re-renders, use React Compiler for automatic memoization\n- After profiling shows broad store/context updates, use atomic state (Jotai/Zustand) to reduce re-renders\n- Use `useDeferredValue` for expensive computations\n\n### Critical: Bundle Size\n\n**Analyze bundle:**\n```bash\nnpx react-native bundle \\\n  --entry-file index.js \\\n  --bundle-output output.js \\\n  --platform ios \\\n  --sourcemap-output output.js.map \\\n  --dev false --minify true\n\nnpx source-map-explorer output.js --no-border-checks\n```\n\n**Verify improvement after optimization:**\n```bash\n# Record baseline size before changes\nls -lh output.js  # e.g., Before: 2.1 MB\n\n# After applying fixes, re-bundle and compare\nnpx react-native bundle --entry-file index.js --bundle-output output.js \\\n  --platform ios --dev false --minify true\nls -lh output.js  # e.g., After: 1.6 MB  (24% reduction)\n```\n\n**Common fixes:**\n- Avoid barrel imports (import directly from source)\n- Remove unnecessary Intl polyfills only after checking Hermes API and method coverage\n- Evaluate tree shaking (Expo SDK 52+ experimental unused import/export removal, or Re.Pack only if already configured)\n- Enable R8 for Android native code shrinking\n\n### High: TTI Optimization\n\n**Measure TTI:**\n- Use `react-native-performance` for markers\n- Only measure cold starts (exclude warm/hot/prewarm)\n\n**Common fixes:**\n- For React Native 0.78 and earlier, disable Android JS bundle compression to enable Hermes mmap\n- Use native navigation (react-native-screens)\n- Preload commonly-used expensive screens before navigating to them\n\n### High: Native Performance\n\n**Profile native:**\n- iOS: Xcode Instruments → Time Profiler\n- Android: Android Studio → CPU Profiler\n\n**Common fixes:**\n- Use background threads for heavy native work\n- Prefer async over sync Turbo Module methods\n- Use C++ for cross-platform performance-critical code\n\n## References\n\nFull documentation with code examples in [references/][references]:\n\n### JavaScript/React (`js-*`)\n\n| File | Impact | Description |\n|------|--------|-------------|\n| [js-lists-flatlist-flashlist.md][js-lists-flatlist-flashlist] | CRITICAL | Replace ScrollView with virtualized lists |\n| [js-profile-react.md][js-profile-react] | MEDIUM | `agent-device react-devtools` profiling |\n| [js-measure-fps.md][js-measure-fps] | HIGH | FPS monitoring and measurement |\n| [js-memory-leaks.md][js-memory-leaks] | MEDIUM | JS memory leak hunting |\n| [js-atomic-state.md][js-atomic-state] | HIGH | Jotai/Zustand patterns |\n| [js-concurrent-react.md][js-concurrent-react] | HIGH | useDeferredValue, useTransition |\n| [js-react-compiler.md][js-react-compiler] | HIGH | Automatic memoization |\n| [js-animations-reanimated.md][js-animations-reanimated] | MEDIUM | Reanimated worklets |\n| [js-bottomsheet.md][js-bottomsheet] | HIGH | Bottom sheet optimization |\n| [js-uncontrolled-components.md][js-uncontrolled-components] | HIGH | TextInput optimization |\n\n### Native (`native-*`)\n\n| File | Impact | Description |\n|------|--------|-------------|\n| [native-turbo-modules.md][native-turbo-modules] | HIGH | Building fast native modules |\n| [native-sdks-over-polyfills.md][native-sdks-over-polyfills] | HIGH | Native vs JS libraries |\n| [native-measure-tti.md][native-measure-tti] | HIGH | TTI measurement setup |\n| [native-threading-model.md][native-threading-model] | HIGH | Turbo Module threads |\n| [native-profiling.md][native-profiling] | MEDIUM | Xcode/Android Studio profiling |\n| [native-platform-setup.md][native-platform-setup] | MEDIUM | iOS/Android tooling guide |\n| [native-view-flattening.md][native-view-flattening] | MEDIUM | View hierarchy debugging |\n| [native-memory-patterns.md][native-memory-patterns] | MEDIUM | C++/Swift/Kotlin memory |\n| [native-memory-leaks.md][native-memory-leaks] | MEDIUM | Native memory leak hunting |\n| [native-android-16kb-alignment.md][native-android-16kb-alignment] | CRITICAL | Third-party library alignment for Google Play |\n\n### Bundling (`bundle-*`)\n\n| File | Impact | Description |\n|------|--------|-------------|\n| [bundle-barrel-exports.md][bundle-barrel-exports] | CRITICAL | Avoid barrel imports |\n| [bundle-analyze-js.md][bundle-analyze-js] | CRITICAL | JS bundle visualization |\n| [bundle-tree-shaking.md][bundle-tree-shaking] | HIGH | Dead code elimination |\n| [bundle-analyze-app.md][bundle-analyze-app] | HIGH | App size analysis |\n| [bundle-r8-android.md][bundle-r8-android] | HIGH | Android code shrinking |\n| [bundle-hermes-mmap.md][bundle-hermes-mmap] | HIGH | Disable bundle compression |\n| [bundle-native-assets.md][bundle-native-assets] | HIGH | Asset catalog setup |\n| [bundle-library-size.md][bundle-library-size] | MEDIUM | Evaluate dependencies |\n| [bundle-code-splitting.md][bundle-code-splitting] | MEDIUM | Remote chunk loading safeguards |\n\n## Problem → Skill Mapping\n\n| Problem | Start With |\n|---------|------------|\n| App feels slow/janky | [js-measure-fps.md][js-measure-fps] → [js-profile-react.md][js-profile-react] |\n| Too many re-renders | [js-profile-react.md][js-profile-react] → [js-react-compiler.md][js-react-compiler] |\n| Slow startup (TTI) | [native-measure-tti.md][native-measure-tti] → [bundle-analyze-js.md][bundle-analyze-js] |\n| Large app size | [bundle-analyze-app.md][bundle-analyze-app] → [bundle-r8-android.md][bundle-r8-android] |\n| Memory growing | [js-memory-leaks.md][js-memory-leaks] or [native-memory-leaks.md][native-memory-leaks] |\n| Animation drops frames | [js-animations-reanimated.md][js-animations-reanimated] |\n| Bottom sheet jank/re-renders | [js-bottomsheet.md][js-bottomsheet] → [js-animations-reanimated.md][js-animations-reanimated] |\n| List scroll jank | [js-lists-flatlist-flashlist.md][js-lists-flatlist-flashlist] |\n| TextInput lag | [js-uncontrolled-components.md][js-uncontrolled-components] |\n| Native module slow | [native-turbo-modules.md][native-turbo-modules] → [native-threading-model.md][native-threading-model] |\n| Native library alignment issue | [native-android-16kb-alignment.md][native-android-16kb-alignment] |\n\n[references]: references/\n[js-lists-flatlist-flashlist]: references/js-lists-flatlist-flashlist.md\n[js-profile-react]: references/js-profile-react.md\n[js-measure-fps]: references/js-measure-fps.md\n[js-memory-leaks]: references/js-memory-leaks.md\n[js-atomic-state]: references/js-atomic-state.md\n[js-concurrent-react]: references/js-concurrent-react.md\n[js-react-compiler]: references/js-react-compiler.md\n[js-animations-reanimated]: references/js-animations-reanimated.md\n[js-bottomsheet]: references/js-bottomsheet.md\n[js-uncontrolled-components]: references/js-uncontrolled-components.md\n[native-turbo-modules]: references/native-turbo-modules.md\n[native-sdks-over-polyfills]: references/native-sdks-over-polyfills.md\n[native-measure-tti]: references/native-measure-tti.md\n[native-threading-model]: references/native-threading-model.md\n[native-profiling]: references/native-profiling.md\n[native-platform-setup]: references/native-platform-setup.md\n[native-view-flattening]: references/native-view-flattening.md\n[native-memory-patterns]: references/native-memory-patterns.md\n[native-memory-leaks]: references/native-memory-leaks.md\n[native-android-16kb-alignment]: references/native-android-16kb-alignment.md\n[bundle-barrel-exports]: references/bundle-barrel-exports.md\n[bundle-analyze-js]: references/bundle-analyze-js.md\n[bundle-tree-shaking]: references/bundle-tree-shaking.md\n[bundle-analyze-app]: references/bundle-analyze-app.md\n[bundle-r8-android]: references/bundle-r8-android.md\n[bundle-hermes-mmap]: references/bundle-hermes-mmap.md\n[bundle-native-assets]: references/bundle-native-assets.md\n[bundle-library-size]: references/bundle-library-size.md\n[bundle-code-splitting]: references/bundle-code-splitting.md\n\n## Attribution\n\nBased on \"The Ultimate Guide to React Native Optimization\" by Callstack.\n"
}

SHA-256: 8ac4bd568a3e7a9030e409210f3533a73d6407eac31d48106d051c7c3709fddb