React Native

Cross-platform iOS and Android apps from one TypeScript codebase.

adds it to an existing project · no account needed
Currentas published in v1.5.1

The rule

This is the whole text, exactly as your agent receives it. Nothing is held back for the paid tier.

Components

  • Function components with typed props. No class components.
  • One screen per file; extract a component once a screen passes ~150 lines.
  • StyleSheet.create at the bottom of the file — never inline style objects in render, which allocates a new object every frame.
  • Platform differences go in Platform.select, or a .ios.tsx / .android.tsx pair when the whole component differs.

Layout

  • Flexbox only. flexDirection defaults to column — the opposite of the web.
  • Never hardcode screen dimensions. Use flex, useWindowDimensions, and SafeAreaView for notches and home indicators.
  • Wrap text in <Text>. A bare string inside <View> crashes at runtime.

Lists

  • FlatList or FlashList, never .map() over fetched data — an unvirtualised list of 500 rows mounts 500 components.
  • keyExtractor returns a stable id, not the index.
  • Memoise renderItem and keep row components pure, or every parent render re-renders every visible row.

Images

  • Always give remote images explicit width/height; without them layout jumps when they load.
  • Ship assets at display size. A 4000px source scaled into a 100px avatar costs full decode memory on every render.

Platform APIs

  • Request permissions immediately before the action that needs them, with an explanation — not on app start.
  • Handle the denied case as a real UI state, not an alert-and-hope.
  • Anything touching the native layer goes behind a service, so it can be mocked.

Performance

  • Profile in a release build; debug builds are misleading.
  • Keep useEffect dependency arrays honest. Do not disable the lint rule.
  • Clean up subscriptions, timers and listeners on unmount.

Never

  • Never edit ios/ or android/ generated files by hand.
  • Never leave console.log in shipped code.
  • Never assume a JS reload picks up a native module change — rebuild.

6 formats, one per tool

Each tab is the file that tool actually reads, at the path it actually looks in. Knowing where each one looks is most of the work of supporting it.

.cursor/rules/react-native.mdchand-written
---
description: React Native conventions
globs: ["**/*.tsx", "src/**/*.ts"]
alwaysApply: false
---

# React Native

## Components

- Function components with typed props. No class components.
- One screen per file; extract a component once a screen passes ~150 lines.
- `StyleSheet.create` at the bottom of the file — never inline style objects in
  render, which allocates a new object every frame.
- Platform differences go in `Platform.select`, or a `.ios.tsx` / `.android.tsx`
  pair when the whole component differs.

## Layout

- Flexbox only. `flexDirection` defaults to `column` — the opposite of the web.
- Never hardcode screen dimensions. Use flex, `useWindowDimensions`, and
  `SafeAreaView` for notches and home indicators.
- Wrap text in `<Text>`. A bare string inside `<View>` crashes at runtime.

## Lists

- `FlatList` or `FlashList`, never `.map()` over fetched data — an unvirtualised
  list of 500 rows mounts 500 components.
- `keyExtractor` returns a stable id, not the index.
- Memoise `renderItem` and keep row components pure, or every parent render
  re-renders every visible row.

## Images

- Always give remote images explicit `width`/`height`; without them layout jumps
  when they load.
- Ship assets at display size. A 4000px source scaled into a 100px avatar costs
  full decode memory on every render.

## Platform APIs

- Request permissions immediately before the action that needs them, with an
  explanation — not on app start.
- Handle the denied case as a real UI state, not an alert-and-hope.
- Anything touching the native layer goes behind a service, so it can be mocked.

## Performance

- Profile in a release build; debug builds are misleading.
- Keep `useEffect` dependency arrays honest. Do not disable the lint rule.
- Clean up subscriptions, timers and listeners on unmount.

## Never

- Never edit `ios/` or `android/` generated files by hand.
- Never leave `console.log` in shipped code.
- Never assume a JS reload picks up a native module change — rebuild.

Hand-written by the module author, frontmatter and all. It is the source the four derived formats are rendered from, so a correction lands here first.

What else this module writes

The rule is one file of several. Selecting React Native contributes all of this too — merged with every other module you pick, with conflicts resolved rather than duplicated.

Dependencies
react^19.2.3react-native^0.86.0react-native-safe-area-context^5.8.0react-native-screens^4.26.0@types/react^19.2.0dev
Folders
src/components/src/features/src/hooks/src/navigation/src/services/src/theme/src/utils/assets/images/assets/fonts/

Advisory history

Every time this rule turned out to be wrong, and what we did about it.

No corrections yet

This rule has been accurate since it was published. That is a fact about the rule, not a promise about the future — which is the whole reason this section exists.

Pro tells you the day a correction lands that affects a repo you actually have.

See what Pro adds →
Put this rule in a real project

The wizard picks the rest of the stack with you, writes all 6 formats, and leaves a manifest so check can tell you when any of it drifts.