Skip to content
Back to skills

React Native

ASecurity

React Native and Expo rules, patterns, and checklists. Load when react-native is detected.

  • 6 stars
  • 0 votes
  • 0 copies
  • 0 views
  • Added September 6, 2026
developmentjavascripttypescriptgojavaswiftkotlinreacttestinggitapi

Works with

  • cli
  • api

Security analysis

A100/100

Pro scans all 4 files and shows the line behind each finding

Scanned September 6, 2026

npx -y skills add Dev-Toolbelt/dev-team-agents --skill react-native --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of React Native?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for React Native
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/dev-toolbelt-react-native/badge)](https://www.skillsdirectory.com/skills/dev-toolbelt-react-native)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: react-native
description: React Native and Expo rules, patterns, and checklists. Load when react-native is detected.
---

## Detection Signals

Load this skill when **any** of the following are found:

| Signal | File / Dependency |
|--------|------------------|
| `react-native` in `package.json` dependencies | `package.json` |
| Metro bundler config | `metro.config.js` / `metro.config.ts` |
| React Native CLI project | `android/` + `ios/` directories together |
| Expo project | `app.json` with `"expo"` key, `eas.json`, or `expo` in `package.json` |
| Expo Modules | `expo-modules-core` in `package.json` |

---

## Project Structure

```
src/
├── app/           # Root navigation and app entry
├── components/    # Reusable, platform-agnostic UI components
├── screens/       # Screen-level components (one per route)
├── hooks/         # Custom hooks (no UI, no side effects tied to render)
├── store/         # Global state (Redux, Zustand, Jotai)
├── services/      # API clients, native module wrappers
├── utils/         # Pure functions, formatters, constants
├── types/         # Shared TypeScript types and interfaces
└── assets/        # Images, fonts, icons
```

- One screen = one file; never put multiple screens in one file
- Platform-specific files use `.ios.tsx` / `.android.tsx` suffixes — only when unavoidable
- Shared business logic must live in hooks or services, never inside screen components

---

## Expo: Managed vs Bare Workflow

→ Load `skills/mobile/react-native/references/expo-vs-bare.md` when deciding between Managed and Bare workflows, configuring EAS Build, or handling OTA updates.

---

## Navigation

→ Load `skills/mobile/react-native/references/navigation.md` when working with React Navigation, deep links, or back behavior.

---

## State Management

→ Load `skills/mobile/react-native/references/state-management.md` when choosing or implementing state management (Zustand, Redux Toolkit, Jotai, TanStack Query).

---

## Performance

### Lists
- **Always use `FlatList` or `SectionList`** for dynamic lists — never `ScrollView` + `.map()` for more than ~10 items
- Prefer **FlashList** (`@shopify/flash-list`) over `FlatList` for large lists (> 100 items) — it is significantly faster
- Set `keyExtractor` to a stable, unique string — never use array index
- Use `getItemLayout` when item height is fixed to skip measurement overhead
- `removeClippedSubviews={true}` for long lists on Android

### Renders
- `React.memo` on components that receive stable props and re-render often
- `useCallback` on functions passed as props to memoized children
- `useMemo` only for genuinely expensive computations — not as a default
- Avoid anonymous functions and inline objects in JSX props (create new references each render)

### Images
- Use `expo-image` or `react-native-fast-image` instead of the built-in `Image` — both support caching and progressive loading
- Always specify `width` and `height` — never let images cause layout shift
- Use WebP format for all non-transparent images

### JavaScript Engine
- **Hermes** is enabled by default in React Native 0.70+ and all Expo SDK 47+ projects — do not disable it
- Profile with Flipper (bare) or React DevTools Profiler (both workflows) before optimizing

---

## Native Integrations

### Permissions (Runtime)
Always request permissions at the moment they are needed, not at app launch:

```tsx
import * as Location from 'expo-location'; // Managed
// or
import { request, PERMISSIONS } from 'react-native-permissions'; // Bare

const requestLocation = async () => {
  const { status } = await Location.requestForegroundPermissionsAsync();
  if (status !== 'granted') {
    // Show rationale or graceful degradation — never crash
  }
};
```

- Check permission status before requesting — avoid re-prompting after a denial
- Always handle the `denied` and `blocked` states gracefully
- On iOS: populate all `NSUsageDescription` keys in `app.json → ios.infoPlist` before submitting

### Push Notifications
- Use `expo-notifications` (Managed) or `@react-native-firebase/messaging` (Bare/Firebase)
- Always request permission before registering for push tokens
- Store the device token server-side tied to the user, not the device
- Handle foreground, background, and quit-state notifications explicitly

### Expo Modules API (custom native modules)
When a native module is not available in the Expo SDK:
1. Create an Expo Module: `npx create-expo-module my-module`
2. Implement in Swift (iOS) and Kotlin (Android) within the module
3. Export via `ExpoModulesCore` — avoids the old bridge entirely
4. For Bare workflow: native modules can still use the traditional bridge, but prefer the new architecture (TurboModules) for new code

---

## Security

- **Never hardcode API keys or secrets** in JS code — they end up in the bundle; use environment variables via `expo-constants` or a secrets manager
- **Secure storage for tokens**: `expo-secure-store` (Managed) or `react-native-keychain` (Bare) — both use iOS Keychain and Android Keystore
- **Certificate pinning**: implement for apps handling financial or health data
- **Jailbreak/root detection**: use `expo-device` (`isRooted`) or `react-native-jail-monkey` for sensitive apps
- **Network**: enforce HTTPS; configure App Transport Security (iOS) and Network Security Config (Android) to disallow cleartext

---

## Testing

| Layer | Tool | Purpose |
|-------|------|---------|
| Unit | **Jest** + `@testing-library/react-native` | Component rendering and hooks |
| Integration | **Detox** | Full device E2E (real device or simulator) |
| Manual | Physical device on each target OS version | Permissions, gestures, platform quirks |

- Test on a **real device** before any release — simulators do not replicate memory pressure, battery, or actual GPU behavior
- Detox tests must run in CI against the `preview` build profile
- Snapshot tests: use sparingly — they break on any style change and add noise

---

## App Store & Play Store — Publication Checklist

### Both Platforms
- [ ] App icon in all required sizes (use `expo-icon-generator` or Sketch/Figma export)
- [ ] Splash screen tested on all target screen sizes
- [ ] Version (`version`) and build number (`ios.buildNumber` / `android.versionCode`) incremented
- [ ] No development/debug code in production build (`__DEV__` guards removed)
- [ ] Privacy policy URL set in store listing and `app.json` (required for apps accessing camera, location, contacts)
- [ ] App tested on minimum supported OS version

### iOS (App Store)
- [ ] `bundleIdentifier` matches App Store Connect entry
- [ ] Signing configured: distribution certificate + provisioning profile (or EAS Credentials)
- [ ] All `NSUsageDescription` keys populated in `infoPlist`
- [ ] TestFlight build tested by at least one external tester
- [ ] Age rating and content declarations filled in App Store Connect
- [ ] App Review notes added for any feature requiring special permissions

### Android (Play Store)
- [ ] `package` name matches Play Console entry
- [ ] Upload keystore stored securely (EAS Credentials or password manager) — **never commit to git**
- [ ] `targetSdkVersion` ≥ current Google Play requirement (updated annually)
- [ ] Adaptive icon configured (`android.adaptiveIcon`)
- [ ] Internal / Closed testing track tested before production rollout
- [ ] Data safety section filled in Play Console

Files in this skill

  • SKILL.md7.3 KB
  • references/expo-vs-bare.md2.6 KB
  • references/navigation.md1 KB
  • references/state-management.md946 B

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.