Skip to content
Skill · Cursor.cursorrulesCoding

React Native + Expo Rules

Expo project rules covering typed expo-router navigation, platform-split files, asset and font handling, and list performance.

Use when: Use in Expo SDK 50+ apps with expo-router and TypeScript to keep navigation type-safe and platform-specific code contained.

@libraryNewcomer
0 upvotes0 forks0 comments

The skill file

Cursor · .cursorrules
.cursorrules3493 chars
You are working in an Expo (managed workflow) app with expo-router and strict TypeScript. ## Navigation - expo-router file-based routes only — never install or generate raw `@react-navigation` stack/tab setup by hand; expo-router wraps it. - Typed routes are on (`experiments.typedRoutes: true` in app.json). Navigate with `<Link href="/profile/[id]" />` or `router.push({ pathname: "/profile/[id]", params: { id } })` — never a template-string path, which bypasses route typing. - Read params with `useLocalSearchParams<{ id: string }>()` and validate/coerce immediately; params are always strings. - Route groups organize layout, not URLs: auth screens under `app/(auth)/`, tabs under `app/(tabs)/`. Screens private to a route live in a co-located `components/` folder outside `app/` (only routes live in `app/`). - Auth gating happens in a layout via `<Redirect href="/sign-in" />` after the session loads — never `router.replace` inside a screen's `useEffect`. ## Platform splits - One `Platform.OS` ternary in a file is fine. Two or more, or any platform-specific JSX block, means split the file: `haptics.ios.ts` / `haptics.android.ts` with a shared `haptics.d.ts` (or a common `.ts` fallback) so imports stay `./haptics`. - Platform-specific styling constants (shadows vs elevation, status-bar padding) live in one `theme/platform.ts`, computed once with `Platform.select` — not inline `Platform.select` scattered through StyleSheets. - Never assume safe-area insets: wrap screens in `SafeAreaView` from `react-native-safe-area-context` (not the core one) or use `useSafeAreaInsets()` for fine control. - Web is a target too: no direct `window`/`document` access outside `.web.ts` files; check `Platform.OS === "web"` before native-only modules. ## Assets, fonts, images - Static assets are imported (`require("@/assets/images/logo.png")`) so Metro bundles and hashes them — never hardcoded file paths or remote URLs for things that ship with the app. - Use `expo-image` (`<Image>` with `contentFit`, `transition`, `cachePolicy`) instead of core `Image` everywhere. Give every remote image an explicit size or flex constraint; an unsized image is a layout bug. - Fonts load via `expo-font` config plugin in app.json (embedded at build time), not runtime `useFonts`, unless the font is genuinely dynamic. - Icons come from `@expo/vector-icons` only; no ad-hoc icon PNGs. ## Components and style - `StyleSheet.create` at file bottom, or NativeWind classes if the project has it — never inline style objects in JSX (they re-allocate every render), except a single dynamic value merged as `[styles.box, { height }]`. - Long lists: `FlashList` (or `FlatList` with `keyExtractor` returning a stable id). Never render a list by `.map` inside a `ScrollView` past ~10 items. - Touchables: `Pressable` with `hitSlop` of at least 8 on small targets; no deprecated `TouchableOpacity` in new code. - Keyboard handling on every form screen: `KeyboardAvoidingView` with `behavior={Platform.OS === "ios" ? "padding" : "height"}`, plus `keyboardShouldPersistTaps="handled"` on the enclosing scroll view. ## Config and native modules - Secrets and environment switches go through `app.config.ts` `extra` + `expo-constants` (or `EXPO_PUBLIC_*` vars for client-safe values) — never a committed `.env` read at runtime. - Any library with native code must be Expo-compatible (config plugin or included in the Expo SDK). Adding one means a new dev client build — call that out in the PR description.

Install

drop into your repo

Save this to your project or home directory so Cursor can load it.

path./.cursorrules
Discussion

What people are saying

Forks

0 forks of this skill
Loading forks…