From qe-framework
Builds, optimizes, and debugs cross-platform mobile apps with React Native and Expo. Handles navigation, native modules, FlatList performance, and platform-specific code.
How this skill is triggered — by the user, by Claude, or both
Slash command
/qe-framework:Qreact-native-expertThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
Senior mobile engineer building production-ready cross-platform applications with React Native and Expo.
Senior mobile engineer building production-ready cross-platform applications with React Native and Expo.
npx expo doctor to verify environment and SDK compatibility; fix any reported issues before proceedingnpx expo start --clear, then restartnpx expo run:iosadb logcat or Gradle output → resolve SDK/NDK version mismatch → rebuild with npx expo run:androidnpx expo install <module> to ensure compatible version, then rebuild native layersLoad detailed guidance based on context:
| Topic | Reference | Load When |
|---|---|---|
| Navigation | references/expo-router.md | Expo Router, tabs, stacks, deep linking |
| Platform | references/platform-handling.md | iOS/Android code, SafeArea, keyboard |
| Lists | references/list-optimization.md | FlatList, performance, memo |
| Storage | references/storage-hooks.md | AsyncStorage, MMKV, persistence |
| Structure | references/project-structure.md | Project setup, architecture |
/**
* HomeScreen - Main navigation entry point
* @param {NavigationProp<RootStackParamList>} navigation - React Navigation instance
* @param {RouteProp<RootStackParamList, 'Home'>} route - Route params including refresh trigger
* @returns {React.ReactElement} Rendered screen
*/
export function HomeScreen({ navigation, route }: {
navigation: NavigationProp<RootStackParamList>;
route: RouteProp<RootStackParamList, 'Home'>;
}): React.ReactElement {
useEffect(() => {
const unsubscribe = navigation.addListener('focus', () => {
console.log('Screen focused, refresh data if route.params?.refresh === true');
});
return unsubscribe;
}, [navigation, route.params?.refresh]);
return <View><Text>Home</Text></View>;
}
/**
* CrashBoundary wraps screens to catch unhandled exceptions
* @param {React.ReactNode} children - Child components to protect
* @param {(err: Error) => void} onError - Callback to report to Sentry/Bugsnag
*/
class CrashBoundary extends React.Component<{ children: React.ReactNode; onError: (e: Error) => void }, { hasError: boolean }> {
componentDidCatch(error: Error) {
this.props.onError(error);
this.setState({ hasError: true });
}
render() {
return this.state.hasError ? <ErrorFallback /> : this.props.children;
}
}
/**
* ItemList - Virtualized list for 1000+ items
* @param {Item[]} data - Array of items to render
* @param {(id: string) => void} onItemPress - Press handler
* @returns {React.ReactElement} FlatList with memoized items
*/
export const ItemList = memo(({ data, onItemPress }: { data: Item[]; onItemPress: (id: string) => void }) => (
<FlatList
data={data}
keyExtractor={(item) => item.id}
renderItem={({ item }) => <MemoItem item={item} onPress={onItemPress} />}
getItemLayout={(data, index) => ({ length: 60, offset: 60 * index, index })}
removeClippedSubviews
maxToRenderPerBatch={10}
/>
));
All React Native code must include JSDoc headers:
navigation (NavigationProp), route (RouteProp with param type), params via route.params@param for dependencies, @returns for state/side-effect resulttsc --noEmit before commit--write on all .tsx files--minify=true in production builds| ❌ Wrong | ✅ Correct |
|---|---|
Inline styles in render/loop: <View style={{ padding: 16 }} /> | Use StyleSheet.create outside component |
| ScrollView for 100+ items | Use FlatList with getItemLayout for virtualization |
| Synchronous bridge calls blocking JS thread | Use async bridge methods with callbacks/promises |
| TextInput without KeyboardAvoidingView | Wrap forms in KeyboardAvoidingView per platform |
| Storing secrets in AsyncStorage | Use react-native-keychain for sensitive data |
When implementing React Native features, deliver:
Platform.select or .ios.tsx / .android.tsx splits as neededReact Native 0.73+, Expo SDK 50+, Expo Router, React Navigation 7, Reanimated 3, Gesture Handler, AsyncStorage, MMKV, React Query, Zustand
npx claudepluginhub inho-team/qe-framework --plugin qe-frameworkCreates, edits, and optimizes skills for Claude Code, including drafting, evaluating with test prompts, iterating on performance, and improving skill descriptions for better triggering accuracy.