Cursor Rules for React Native and Expo Projects

A practical Cursor rules template for React Native and Expo: platform-specific code, navigation, permissions, and device checks, with fenbs holding shared mobile decisions and the current handoff.

Updated 4 min read

Cursor rules for React Native and Expo tell a coding assistant which platform patterns your project uses, how navigation is structured, how permissions are requested, and what device-specific checks are required before a feature is ready. Without them, an assistant may write code that runs on iOS but fails on Android, use a deprecated navigation API, or skip a permission check that the app store review process will catch. fenbs keeps the shared mobile product decisions and the current handoff across sessions, so a new Cursor session knows where the last one stopped.

This page provides a working template for each concern and explains why these areas are where most mobile AI coding mistakes appear.

Why React Native and Expo need their own Cursor rules

React Native looks like React but has different constraints. Styles are not CSS. The component tree has different primitives. Platform differences require explicit handling. Expo adds a managed workflow with its own config plugin system, a set of pre-built native modules, and a specific upgrade path. A general React rule file does not cover these areas, and an assistant working from web React knowledge will produce code that compiles but behaves incorrectly on a device.

Separate rule files for React Native let you update mobile conventions independently as Expo SDK versions change, without touching the web rules. See the Cursor rules hierarchy guide for how to layer these files alongside your existing project rules.

The value of mobile-specific rules becomes clear after the first session where an assistant writes a component using web assumptions. An inline style object that works in a browser renders differently on a physical device. A navigation call that works in a simulator fails on a real Android handset with a different back-gesture configuration. Rules built from real mistakes on real devices are more useful than rules written before the project has shipped a screen. Keep a note each time an assistant makes a platform-specific mistake and turn the recurring ones into rules. A rule built from a real device failure is more reliable than one written in advance because it names the exact pattern that caused the problem, not a hypothetical one.

Platform-specific code rules

Platform-specific code is the area where an assistant most often gets it quietly wrong. A component that works on iOS may crash or look broken on Android. The rule needs to name which patterns your project uses for platform branching and which it avoids.

Example platform-specific rules for .cursor/rules/react-native-platform.mdc
# React Native platform rules

## Platform branching
Use Platform.select or Platform.OS when a behavior or style must differ by platform.
Do not use separate <Component>.ios.tsx and <Component>.android.tsx files unless the
difference is large enough to justify two full implementations.

## Styles
Use StyleSheet.create for all styles. Do not use inline style objects as literals in JSX
(they create new objects on every render).
Do not use web CSS properties: box-shadow uses shadow* props on iOS and elevation on Android.
Use the elevation prop for Android shadows.

## Text
Wrap all visible text in a <Text> component. Raw strings in a View are not valid in React Native.
Use numberOfLines and adjustsFontSizeToFit when text containers have a fixed height.

## Images
Use the Image component from react-native or expo-image for local assets.
Use uri sources only with explicit width and height, or a flex-based container.

Navigation rules

The navigation library and pattern is one of the most consequential decisions in a React Native project. Mixing React Navigation and Expo Router in the same project causes confusion. Rules that state which library is in use and how routes are named prevent an assistant from generating navigation code for the wrong system.

Example navigation rules
# React Native navigation

## Navigation library
This project uses Expo Router (file-based routing). Do not generate React Navigation
stack or tab navigator code; all navigation is driven by the file tree in app/.

## Route files
Route files live in app/. Layout files are named _layout.tsx.
Tab routes live in app/(tabs)/. Modal routes live in app/(modals)/.
Dynamic segments use [param].tsx.

## Navigation calls
Use the router from expo-router:
  import { router } from 'expo-router';
  router.push('/profile');
  router.replace('/home');

Do not use useNavigation from @react-navigation/native unless the project
already imports it for a specific integration.

## Back behavior
Prefer router.back() over router.push() when returning to a previous screen.
Use router.dismiss() to close a modal and return to the underlying screen.

Permission and capability rules

Permission handling is an area where a small omission causes an app store rejection or a runtime crash on a physical device. An assistant that does not know your project's patterns may request permissions at the wrong time, skip the denial state, or use a deprecated API. Rules in this area function as a checklist: every permission use must go through a defined pattern. The permission rules also need to address the case where the user has denied a permission and then changes the system setting. Your app must handle the state where the permission was previously denied, the user reopened System Settings, and the app resumes with a newly granted permission. Rules that only cover the initial request often miss this re-entry path.

Example permission rules
# Permissions and capabilities

## Request timing
Request permissions at the moment the feature is first used, not at app launch.
Show a brief explanation to the user before calling the permission API.

## Permission pattern
Use the expo permissions package that matches the feature:
  expo-camera → Camera.requestCameraPermissionsAsync()
  expo-location → Location.requestForegroundPermissionsAsync()
  expo-media-library → MediaLibrary.requestPermissionsAsync()

Always handle all three outcomes: granted, denied, and undetermined.
Provide a fallback UI when permission is denied; do not hide the feature silently.

## Never assume granted
After a permission request, check the returned status before calling the native API.
Do not assume a previously granted permission is still granted on re-launch.

## Device-only features
Wrap calls to camera, GPS, biometrics, and NFC in a capability check.
Use expo-device or the relevant module's isAvailableAsync to check before requesting.

Expo-specific rules

Expo Managed Workflow has its own constraints. Config plugins change native code at build time, not at runtime; an assistant that writes a native module call without checking whether the plugin is installed will produce code that compiles but fails on the device. Rules for Expo should name the SDK version, list which plugins are installed, and explain the build and update workflow.

Example Expo managed workflow rules
# Expo managed workflow

## SDK version
This project targets Expo SDK 57. Do not suggest APIs removed before SDK 57
or experimental APIs that require a bare workflow.

## Installed plugins
Config plugins installed in this project:
  expo-camera, expo-location, expo-notifications, expo-media-library,
  expo-secure-store, expo-file-system.
Do not add calls to modules not in this list without first adding the plugin.

## EAS Build
Build profiles are in eas.json. The development profile uses an internal distribution.
Do not change eas.json without confirming the change with the team.

## OTA updates
This project uses Expo Updates for over-the-air patches. Native changes require a full
EAS Build; JS-only changes can be pushed with eas update.
How fenbs helps

Keep mobile decisions and the current handoff in one place

fenbs keeps the shared mobile product decisions your team has agreed on and the current Where we left off for the app. When a Cursor session ends mid-feature, save progress to fenbs: what was completed, what was tested on device, and what the next step is. The next session reads that before opening a component file. fenbs does not connect to a physical device, but it keeps the context that bridges one session to the next.

Create a free account

Free for one person · No credit card · Works with Claude, ChatGPT, Cursor and more

How to do this with fenbs

  1. Create a free account and add a project for your React Native or Expo app.
  2. Record the key mobile product decisions in fenbs: which navigation library is in use, the Expo SDK version, which permissions the app uses, and any platform-specific rules your team has agreed on.
  3. Connect Cursor to fenbs over MCP from Integrations. Ask Cursor to read the project context before working on a mobile screen or component.
  4. Save progress in fenbs before each session ends: the component worked on, what was tested on a device or simulator, and the next step. This is the handoff that saves a long explanation next time.
  5. When the Expo SDK version changes, update the rule file and the Decision in fenbs together. The two should always agree.

Questions people ask.

Should I have separate Cursor rule files for iOS and Android?

Only if the differences are large enough to justify separate files. Most teams use one rule file with Platform.select guidance. If your project has large platform-divergent areas, a platform-specific glob pattern can attach a supplementary rule file only when an .ios.tsx or .android.tsx file is open.

Do these rules work with bare workflow Expo projects?

The navigation and permission rules apply to both managed and bare workflows. The Expo-specific section should be adjusted for bare workflow: you manage native modules directly, config plugins still apply, and EAS Build profiles may differ from managed workflow defaults.

How do I handle rules for a project that uses both React Native and a web target?

Use separate rule files scoped by glob pattern. A rule file matching app/ covers the mobile app, while a rule file matching web/ covers the web target. Shared logic in packages/ can have its own rule file. The Cursor rules hierarchy guide explains how to layer these files.

What is the most common mistake an AI makes in React Native projects?

Writing StyleSheet styles using CSS properties that do not exist in React Native, such as box-shadow instead of the shadow props and elevation. A close second is generating permission requests without handling the denied case. Both are preventable with specific rules.

More in Prompts and skills for AI work

All Prompts and skills for AI work articles

Start with one thing.

Free for one person · No credit card · Works with Claude, ChatGPT, Cursor and more

There is nothing to set up first. Write one line and you’ve started.