react-native
React Native patterns for mobile app development with Expo and bare workflow. Trigger: When building mobile apps, working with React Native components, using Expo, React Navigation, or NativeWind.
Best use case
react-native is best used when you need a repeatable AI agent workflow instead of a one-off prompt.
React Native patterns for mobile app development with Expo and bare workflow. Trigger: When building mobile apps, working with React Native components, using Expo, React Navigation, or NativeWind.
Teams using react-native should expect a more consistent output, faster repeated execution, less prompt rewriting.
When to use this skill
- You want a reusable workflow that can be run more than once with consistent structure.
When not to use this skill
- You only need a quick one-off answer and do not need a reusable workflow.
- You cannot install or maintain the underlying files, dependencies, or repository context.
Installation
Claude Code / Cursor / Codex
Manual Installation
- Download SKILL.md from GitHub
- Place it in
.claude/skills/react-native/SKILL.mdinside your project - Restart your AI agent — it will auto-discover the skill
How react-native Compares
| Feature / Agent | react-native | Standard Approach |
|---|---|---|
| Platform Support | Not specified | Limited / Varies |
| Context Awareness | High | Baseline |
| Installation Complexity | Unknown | N/A |
Frequently Asked Questions
What does this skill do?
React Native patterns for mobile app development with Expo and bare workflow. Trigger: When building mobile apps, working with React Native components, using Expo, React Navigation, or NativeWind.
Where can I find the source code?
You can find the source code on GitHub using the link provided at the top of the page.
SKILL.md Source
## When to Use
Load this skill when:
- Building mobile applications with React Native
- Working with Expo managed or bare workflow
- Implementing navigation with React Navigation
- Styling with NativeWind (Tailwind for RN)
- Handling platform-specific code (iOS/Android)
- Managing native modules and linking
## Critical Patterns
### Pattern 1: Project Structure
```
src/
├── app/ # Expo Router screens (if using)
│ ├── (tabs)/ # Tab navigator group
│ ├── (auth)/ # Auth flow group
│ └── _layout.tsx # Root layout
├── components/
│ ├── ui/ # Reusable UI components
│ └── features/ # Feature-specific components
├── hooks/ # Custom hooks
├── services/ # API and external services
├── stores/ # State management (Zustand)
├── utils/ # Utility functions
├── constants/ # App constants, themes
└── types/ # TypeScript types
```
### Pattern 2: Functional Components with TypeScript
Always use functional components with proper typing:
```typescript
import { View, Text, Pressable } from 'react-native';
import type { ViewStyle, TextStyle } from 'react-native';
interface ButtonProps {
title: string;
onPress: () => void;
variant?: 'primary' | 'secondary';
disabled?: boolean;
}
export function Button({
title,
onPress,
variant = 'primary',
disabled = false
}: ButtonProps) {
return (
<Pressable
onPress={onPress}
disabled={disabled}
style={({ pressed }) => [
styles.button,
variant === 'secondary' && styles.buttonSecondary,
pressed && styles.buttonPressed,
disabled && styles.buttonDisabled,
]}
>
<Text style={styles.buttonText}>{title}</Text>
</Pressable>
);
}
```
### Pattern 3: Platform-Specific Code
Use Platform module or file extensions for platform-specific code:
```typescript
import { Platform, StyleSheet } from 'react-native';
// Using Platform.select
const styles = StyleSheet.create({
container: {
paddingTop: Platform.select({
ios: 44,
android: 0,
}),
...Platform.select({
ios: {
shadowColor: '#000',
shadowOffset: { width: 0, height: 2 },
shadowOpacity: 0.1,
shadowRadius: 4,
},
android: {
elevation: 4,
},
}),
},
});
// Or use file extensions:
// Component.ios.tsx
// Component.android.tsx
```
## Code Examples
### Example 1: Expo Router Navigation Setup
```typescript
// app/_layout.tsx
import { Stack } from 'expo-router';
import { StatusBar } from 'expo-status-bar';
export default function RootLayout() {
return (
<>
<StatusBar style="auto" />
<Stack
screenOptions={{
headerShown: false,
animation: 'slide_from_right',
}}
>
<Stack.Screen name="(tabs)" options={{ headerShown: false }} />
<Stack.Screen
name="modal"
options={{
presentation: 'modal',
animation: 'slide_from_bottom',
}}
/>
</Stack>
</>
);
}
```
### Example 2: Custom Hook with React Query
```typescript
// hooks/useUser.ts
import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query';
import { userService } from '@/services/user';
import type { User, UpdateUserInput } from '@/types';
export function useUser(userId: string) {
return useQuery({
queryKey: ['user', userId],
queryFn: () => userService.getById(userId),
staleTime: 5 * 60 * 1000, // 5 minutes
});
}
export function useUpdateUser() {
const queryClient = useQueryClient();
return useMutation({
mutationFn: (data: UpdateUserInput) => userService.update(data),
onSuccess: (_, variables) => {
queryClient.invalidateQueries({ queryKey: ['user', variables.id] });
},
});
}
```
### Example 3: NativeWind Styling
```typescript
// With NativeWind (Tailwind for React Native)
import { View, Text, Pressable } from 'react-native';
import { styled } from 'nativewind';
const StyledPressable = styled(Pressable);
const StyledView = styled(View);
const StyledText = styled(Text);
export function Card({ title, description, onPress }: CardProps) {
return (
<StyledPressable
className="bg-white dark:bg-gray-800 rounded-2xl p-4 shadow-md active:scale-95"
onPress={onPress}
>
<StyledView className="flex-row items-center gap-3">
<StyledView className="w-12 h-12 bg-blue-100 dark:bg-blue-900 rounded-full items-center justify-center">
<StyledText className="text-blue-600 dark:text-blue-300 text-xl">
📱
</StyledText>
</StyledView>
<StyledView className="flex-1">
<StyledText className="text-lg font-semibold text-gray-900 dark:text-white">
{title}
</StyledText>
<StyledText className="text-sm text-gray-500 dark:text-gray-400">
{description}
</StyledText>
</StyledView>
</StyledView>
</StyledPressable>
);
}
```
### Example 4: Safe Area and Keyboard Handling
```typescript
import { KeyboardAvoidingView, Platform } from 'react-native';
import { SafeAreaView } from 'react-native-safe-area-context';
export function ScreenWrapper({ children }: { children: React.ReactNode }) {
return (
<SafeAreaView style={{ flex: 1 }} edges={['top', 'left', 'right']}>
<KeyboardAvoidingView
style={{ flex: 1 }}
behavior={Platform.OS === 'ios' ? 'padding' : 'height'}
keyboardVerticalOffset={Platform.OS === 'ios' ? 0 : 20}
>
{children}
</KeyboardAvoidingView>
</SafeAreaView>
);
}
```
### Example 5: Zustand Store with Persistence
```typescript
// stores/authStore.ts
import { create } from 'zustand';
import { persist, createJSONStorage } from 'zustand/middleware';
import AsyncStorage from '@react-native-async-storage/async-storage';
interface AuthState {
token: string | null;
user: User | null;
isAuthenticated: boolean;
login: (token: string, user: User) => void;
logout: () => void;
}
export const useAuthStore = create<AuthState>()(
persist(
(set) => ({
token: null,
user: null,
isAuthenticated: false,
login: (token, user) => set({ token, user, isAuthenticated: true }),
logout: () => set({ token: null, user: null, isAuthenticated: false }),
}),
{
name: 'auth-storage',
storage: createJSONStorage(() => AsyncStorage),
}
)
);
```
## Anti-Patterns
### Don't: Inline Styles Everywhere
```typescript
// ❌ Bad - inline styles are hard to maintain and don't memoize
export function BadComponent() {
return (
<View style={{ flex: 1, padding: 16, backgroundColor: '#fff' }}>
<Text style={{ fontSize: 18, fontWeight: 'bold', color: '#333' }}>
Title
</Text>
</View>
);
}
// ✅ Good - use StyleSheet or NativeWind
const styles = StyleSheet.create({
container: { flex: 1, padding: 16, backgroundColor: '#fff' },
title: { fontSize: 18, fontWeight: 'bold', color: '#333' },
});
export function GoodComponent() {
return (
<View style={styles.container}>
<Text style={styles.title}>Title</Text>
</View>
);
}
```
### Don't: Use TouchableOpacity for Everything
```typescript
// ❌ Bad - TouchableOpacity is legacy
import { TouchableOpacity } from 'react-native';
// ✅ Good - Use Pressable with feedback
import { Pressable } from 'react-native';
<Pressable
onPress={onPress}
style={({ pressed }) => [
styles.button,
pressed && { opacity: 0.7 }
]}
>
{({ pressed }) => (
<Text style={pressed ? styles.textPressed : styles.text}>
Press Me
</Text>
)}
</Pressable>
```
### Don't: Forget to Handle Loading and Error States
```typescript
// ❌ Bad - no loading/error handling
export function UserProfile({ userId }: { userId: string }) {
const { data } = useUser(userId);
return <Text>{data.name}</Text>; // Will crash if data is undefined
}
// ✅ Good - handle all states
export function UserProfile({ userId }: { userId: string }) {
const { data, isLoading, error } = useUser(userId);
if (isLoading) return <LoadingSpinner />;
if (error) return <ErrorMessage error={error} />;
if (!data) return null;
return <Text>{data.name}</Text>;
}
```
## Quick Reference
| Task | Pattern |
|------|---------|
| Create new Expo project | `npx create-expo-app@latest --template tabs` |
| Add NativeWind | `npx expo install nativewind tailwindcss` |
| Platform check | `Platform.OS === 'ios'` |
| Safe insets | `useSafeAreaInsets()` from `react-native-safe-area-context` |
| Navigation | `router.push('/screen')` with Expo Router |
| Deep linking | Configure in `app.json` under `expo.scheme` |
| Environment vars | Use `expo-constants` or `react-native-dotenv` |
| Icons | `@expo/vector-icons` (included in Expo) |
| Animations | `react-native-reanimated` for 60fps animations |
| Gestures | `react-native-gesture-handler` |
## Resources
- [Expo Documentation](https://docs.expo.dev/)
- [React Native Documentation](https://reactnative.dev/docs/getting-started)
- [Expo Router](https://expo.github.io/router/docs/)
- [NativeWind](https://www.nativewind.dev/)
- [React Navigation](https://reactnavigation.org/docs/getting-started)Related Skills
reactome-database
Query Reactome REST API for pathway analysis, enrichment, gene-pathway mapping, disease pathways, molecular interactions, expression analysis, for systems biology studies.
react-ui-patterns
Modern React UI patterns for loading states, error handling, and data fetching. Use when building UI components, handling async data, or managing UI states.
react-state-management
Master modern React state management with Redux Toolkit, Zustand, Jotai, and React Query. Use when setting up global state, managing server state, or choosing between state management solutions.
react-patterns
Modern React patterns and principles. Hooks, composition, performance, TypeScript best practices.
react-nextjs-development
React and Next.js 14+ application development with App Router, Server Components, TypeScript, Tailwind CSS, and modern frontend patterns.
react-native-expert
Senior React Native and Expo engineer for building production-ready cross-platform mobile apps. Use when building React Native components, implementing navigation with Expo Router, optimizing list and scroll performance, working with animations via Reanimated, handling platform-specific code (iOS/Android), integrating native modules, or structuring Expo projects. Triggers on React Native, Expo, mobile app, iOS app, Android app, cross-platform, native module, FlatList, FlashList, LegendList, Reanimated, Expo Router, mobile performance, app store. Do NOT use for Flutter, web-only React, or backend Node.js tasks.
react-native-executorch
Integrate on-device AI into React Native apps using React Native ExecuTorch, which provides APIs for LLMs, computer vision, OCR, audio processing, and embeddings without cloud dependencies, as well as a variety of pre-exported models for common use cases. Use when user asks to build AI features into mobile apps - AI chatbots, image classification, object detection, style transfer, OCR, document parsing, speech processing, or semantic search - all running locally without cloud dependencies. Use when user mentions offline support, privacy, latency or cost concerns in AI-based applications.
react-native-architecture
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 architecti...
react-modernization
Upgrade React applications to latest versions, migrate from class components to hooks, and adopt concurrent features. Use when modernizing React codebases, migrating to React Hooks, or upgrading to...
react-flow-node-ts
Create React Flow node components with TypeScript types, handles, and Zustand integration. Use when building custom nodes for React Flow canvas, creating visual workflow editors, or implementing no...
react-flow-architect
Expert ReactFlow architect for building interactive graph applications with hierarchical node-edge systems, performance optimization, and auto-layout integration. Use when Claude needs to create or...
react-composition-patterns
React composition patterns that scale. Use when refactoring components with boolean prop proliferation, building flexible component libraries, or designing reusable APIs. Triggers on tasks involving compound components, render props, context providers, or component architecture. Includes React 19 API changes. Do NOT use for React/Next.js performance optimization (use react-best-practices instead).