home/.config/opencode/skill/expo-react-native/SKILL.md
Best practices for developing Expo SDK 54 React Native apps with Expo Router, Zustand, and NativeWind. Use when building mobile apps with this stack, implementing navigation, state management, styling, performance optimization, TypeScript patterns, or security.
npx skillsauth add win20/dotfiles expo-react-nativeInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
SDK 54 defaults to New Architecture (Fabric + TurboModules). SDK 55+ requires it. Check library compatibility at reactnativedirectory.com.
Enable in app.json:
{ "expo": { "experiments": { "reactCompiler": true } } }
Key principle: Default to no manual memoization—the compiler handles useMemo, useCallback, and React.memo automatically.
Manual memoization still needed for:
See references/react-compiler.md for patterns.
Route files (app/) only extract params and delegate to screen components:
// app/profile/index.tsx - Thin route
import { useLocalSearchParams } from 'expo-router';
import { Profile } from '@/screens/profile';
export default function ProfileRoute() {
const { id } = useLocalSearchParams<{ id: string }>();
return <Profile userId={id} />;
}
All business logic lives in screens/. See references/navigation.md for full patterns.
Use selectors to prevent unnecessary re-renders:
// ❌ Subscribes to entire store
const { user } = useAuthStore();
// ✅ Subscribes only to user
const user = useAuthStore((state) => state.user);
See references/state-management.md for store patterns and persistence.
<View className="bg-white rounded-lg p-4 shadow-md">
<Text className={isActive ? 'text-white' : 'text-gray-700'}>{label}</Text>
</View>
Use cssInterop for third-party components. See references/styling.md.
See references/performance.md for list optimization patterns.
Use expo-secure-store for tokens—never AsyncStorage:
await SecureStore.setItemAsync('authToken', token);
await SecureStore.setItemAsync('sensitiveKey', value, { requireAuthentication: true });
| Task | Solution |
|------|----------|
| Navigation | expo-router file-based routes |
| Global state | Zustand with selectors |
| Styling | NativeWind className |
| Secure storage | expo-secure-store |
| Large lists | FlashList |
| Forms | react-hook-form + zod |
development
Best practices for developing Expo SDK 54 React Native apps with Expo Router, Zustand, and NativeWind. Use when building mobile apps with this stack, implementing navigation, state management, styling, performance optimization, TypeScript patterns, or security.
development
Simplify and clarify existing code without changing behavior.
tools
Generate pull request summaries and open GitHub PRs from the current branch’s git changes.
development
Code reviews of git changes without creating actual PR.