Guides React Native development with Expo, focusing on file-based routing, UI safety, and robust API integration.
Install
mkdir -p .claude/skills/expo && curl -L -o skill.zip "https://agentskills.codes/api/skills/download/14247" && unzip -o skill.zip -d .claude/skills/expo && rm skill.zipInstalls to .claude/skills/expo
Activation
This is the description your AI agent reads to decide when to run this skill — the better it matches your request, the more reliably it fires.
Best practices for React Native development with Expo and Expo Router.Key capabilities
- →Implement file-based routing with Expo Router
- →Prevent navigation context crashes
- →Ensure UI reliable against stray text crashes
- →Handle external API responses defensively
- →Manage interactive elements on Android
- →Optimize list modifications with optimistic updates
How it works
The skill provides best practices and rules for Expo and React Native development, covering navigation, styling, API consumption, and performance. It addresses common pitfalls and offers fixes for specific platform behaviors.
Inputs & outputs
When to use expo
- →Implementing file-based routing with Expo Router
- →Handling API responses defensively
- →Preventing common React Native UI crashes
- →Structuring complex navigation logic
About this skill
Expo & React Native Best Practices
Navigation (Expo Router)
- Use File-based routing in the
app/directory. - Use
Linkfromexpo-routerfor navigation, but preferrouter.push()orrouter.replace()for logic-based navigation in event handlers. - Navigation Context Stability: Avoid using
useRouteroruseNavigationdeep inside component trees that are rendered in Modals or Portals.- Constraint: React 19 / NativeWind interop can cause circular navigation context lookups, leading to "Navigation Context" crashes.
- Fix: Elevate navigation logic to the Screen/Page level and pass navigation handlers (like
onClose) down to children.
- Screens should be wrapped in
Stack.ScreenorTabs.Screento configure headers.
Styling & UI Robustness
- Stray Text Crash: React Native crashes if a raw string is outside a
<Text>component.- Caution: Avoid Tailwind patterns like
space-xorspace-yin complex layouts as they inject invisible spacers that can clip into text nodes. Prefer explicit margins (mr-2,mt-4). - JSX Cleanliness: Always ensure there is no accidental whitespace/comments between sibling components in a
View.
- Caution: Avoid Tailwind patterns like
- Loading Guards: Always use an
isLoadingcheck or anErrorBoundarywhen accessing data from a hook (likeuseHousehold). Prevent the UI from rendering withundefinedvalues. - Defensive API Consumption: External APIs (like Open Food Facts) are unreliable.
- Rule: Never trust specific keys exist in a response. Always use extensive optional chaining (
data?.results?.[0]) and fallback to empty defaults (|| []). - Rule: Check
response.okbefore calling.json(). - Rule: Limit "bonus" features. Stick strictly to the user's core intent (e.g., if asked for food search, don't implement full allergy taxonomies that increase surface area for crashes).
- Rule: When searching for products, use localized API endpoints (e.g.,
us.openfoodfacts.org) to ensure results are regionally relevant.
- Rule: Never trust specific keys exist in a response. Always use extensive optional chaining (
- Interactive Layers (Android): Critical: Absolute positioned elements (like dropdowns) that extend beyond their parent container's bounds are non-interactive on Android (clipping).
- Fix: Place floating dropdown containers at the end of the root component (so they are direct children of the page) and use high
elevation(Android) andzIndex(iOS).
- Fix: Place floating dropdown containers at the end of the root component (so they are direct children of the page) and use high
- Nested Scrolling: Avoid nested
ScrollViews. UseFlatListfor dropdowns withnestedScrollEnabled={true},keyboardShouldPersistTaps="always", andpersistentScrollbar={true}. - React 19 / NativeWind Stability (CRITICAL):
- Avoid
classNameon Portals/Modals: When using React 19, NativeWind v4's interop layer may crash when wrapping components logic that uses navigation. - Safe Pattern: For high-interaction components (Modals, FABs, Inputs), use standard React Native
styleprops instead ofclassNameto bypass the interop layer. - Defensive Filtering: Always use optional chaining on dynamic data (e.g.
item.name?.toLowerCase() || '') when filtering lists to prevent crashes during re-renders.
- Avoid
UX & Performance Standards
- Optimistic Updates: For list modifications (add, delete, toggle), update the local state instantly before the API call. Re-fetch or rollback only on error. This gives a "premium" snappy feel.
- Search UX: Every search input MUST have:
- An
X(clear) button inside the input area. - A transparent backdrop
<Pressable>behind the dropdown to dismiss the results when tapping outside.
- An
Auth & Session Management
- Root Auth Gate: Implement a session listener in the
RootLayout(app/_layout.tsx) that renders anAuthScreenif no session is present. This prevents "Logged In" UI loops for users without profiles. - Supabase Mobile Redirects: By default, Supabase redirects email confirmations to
localhost:3000.- Dev Fix: Disable "Confirm Email" in the Supabase dashboard for rapid prototyping.
- Prod Fix: Set the "Site URL" to your app's custom scheme (e.g.,
pantryguard://).
Tooling
- Use
npx expo installto install packages to ensure dependency compatibility. - Dependency Hygiene: Before using a new JS library (like
lodash), check if it requires@types/packages. Install types asdevDependenciesimmediately to prevent TS errors. - Use
Expo Gofor rapid prototyping on physical devices. - Networking Troubleshooting: On Windows, Expo Go may fail with
java.io.IOException(Network Isolation).- Fix 1: Use
npx expo start --tunnelto bypass firewalls. - Fix 2: Ensure Windows network profile is set to Private, not Public.
- Fix 1: Use
Specialized Hardware (Camera/Scanner)
- Library: Use
expo-camera(modernCameraView) rather than the deprecatedexpo-barcode-scanner. - Styling: CRITICAL: Always use inline
style={{ flex: 1 }}forCameraView. Relying onclassName="flex-1"often results in a 0-height container (Black Screen) on certain platforms/plugin versions. - Focus Issues (Android): Barcode scanning on Android often suffers from "blurry focus".
- Fix: Always implement digital zoom controls (
+/-buttons) in the UI. Zooming in (2x/3x) triggers a sensor refocus.
- Fix: Always implement digital zoom controls (
- Permissions: Never assume permission is granted. Handle the
!permission.grantedstate with a dedicated UI.
Push Notifications (Expo Go vs Dev Build)
- CRITICAL: Remote notifications provided by
expo-notificationshave been Removed from the Expo Go Go client (Android) as of SDK 53. - Rule: You MUST guard all notification logic behind an environment check for
ExecutionEnvironment.StoreClient. - Double Guard Pattern:
- Do NOT use top-level
import * as Notifications. Userequire()inside the guarded block. - Do NOT run
setNotificationHandlerorscheduleNotificationAsyncifisExpoGois true. - Log a
[Dev]message instead of crashing.
- Do NOT use top-level
When not to use it
- →When using `useRouter` or `useNavigation` deep inside component trees rendered in Modals or Portals
- →When placing absolute positioned elements that extend beyond their parent container's bounds on Android
- →When using `expo-notifications` remote notifications in Expo Go on Android as of SDK 53
Limitations
- →React 19 / NativeWind interop can cause circular navigation context lookups
- →Absolute positioned elements that extend beyond their parent container's bounds are non-interactive on Android
- →Remote notifications provided by `expo-notifications` have been Removed from the Expo Go client (Android) as of SDK 53
How it compares
This skill offers specific, actionable guidelines and fixes for common Expo and React Native issues, unlike general development advice that might not cover framework-specific constraints or performance optimizations.
Compared to similar skills
expo side by side with the closest alternatives in the catalog.
| Skill | Installs | Updated | Safety | Difficulty |
|---|---|---|---|---|
| expo (this skill) | 0 | 6mo | No flags | Intermediate |
| react-native-architecture | 55 | 2mo | Review | Advanced |
| react-native-design | 33 | 2mo | No flags | Intermediate |
| agent-spec-mobile-react-native | 5 | 6mo | No flags | Intermediate |
Try saying
Example prompts that trigger this skill in your AI assistant.
You might also like
react-native-architecture
wshobson
Build production React Native apps with Expo, navigation, native modules, offline sync, and cross-platform patterns. Use when developing mobile apps, implementing native integrations, or architecting React Native projects.
react-native-design
wshobson
Master React Native styling, navigation, and Reanimated animations for cross-platform mobile development. Use when building React Native apps, implementing navigation patterns, or creating performant animations.
agent-spec-mobile-react-native
ruvnet
Agent skill for spec-mobile-react-native - invoke with $agent-spec-mobile-react-native
heroui-native
heroui-inc
HeroUI Native component library for React Native (Tailwind v4 via Uniwind). Use when working with HeroUI Native components, installing HeroUI Native, customizing themes, or accessing component documentation. Keywords: HeroUI Native, heroui-native, React Native UI, Uniwind.
react-native-expert
Jeffallan
Use when building cross-platform mobile applications with React Native or Expo. Invoke for navigation patterns, platform-specific code, native modules, FlatList optimization.
mobile-developer
sickn33
Develop React Native, Flutter, or native mobile apps with modern architecture patterns. Masters cross-platform development, native integrations, offline sync, and app store optimization. Use PROACTIVELY for mobile features, cross-platform code, or app optimization.