cloudflare-api
Hit the Cloudflare REST API directly for operations that wrangler and MCP can't handle well. Bulk DNS, custom hostnames, email routing, cache purge, WAF rules,…
React Native and Expo patterns for building performant mobile apps. Covers list performance, animations with Reanimated, navigation, UI patterns, state management, platform-specific code, and Expo workflows. Use when building or reviewing React Native code. Triggers: 'react
$ npx -y skills add jezweb/claude-skills --skill react-native --agent claude-codeHow it fires
How this skill gets triggered: by you, by Claude, or both.
/react-nativeContext preview
The summary Claude sees to decide when to auto-load this skill.
React Native and Expo patterns for building performant mobile apps. Covers list performance, animations with Reanimated, navigation, UI patterns, state management, platform-specific code, and Expo workflows. Use when building or reviewing React Native code. Triggers: 'react
name: react-native description: "React Native and Expo patterns for building performant mobile apps. Covers list performance, animations with Reanimated, navigation, UI patterns, state management, platform-specific code, and Expo workflows. Use when building or reviewing React Native code. Triggers: 'react native', 'expo', 'mobile app', 'react native performance', 'flatlist', 'reanimated', 'expo router', 'mobile development', 'ios app', 'android app'." compatibility: claude-code-only allowed-tools: - Read - Write - Edit - Glob - Grep - Bash
Performance and architecture patterns for React Native + Expo apps. Rules ranked by impact — fix CRITICAL before touching MEDIUM.
This is a starting point. The skill will grow as you build more mobile apps.
Lists are the #1 performance issue in React Native. A janky scroll kills the entire app experience.
| Pattern | Problem | Fix | |---------|---------|-----| | **ScrollView for data** | `<ScrollView>` renders all items at once | Use `<FlatList>` or `<FlashList>` — virtualised, only renders visible items | | **Missing keyExtractor** | FlatList without `keyExtractor` → unnecessary re-renders | `keyExtractor={(item) => item.id}` — stable unique key per item | | **Complex renderItem** | Expensive component in renderItem re-renders on every scroll | Wrap in `React.memo`, extract to separate component | | **Inline functions in renderItem** | `renderItem={({ item }) => <Row onPress={() => nav(item.id)} />}` | Extract handler: `const handlePress = useCallback(...)` | | **No getItemLayout** | FlatList measures every item on scroll (expensive) | Provide `getItemLayout` for fixed-height items: `(data, index) => ({ length: 80, offset: 80 * index, index })` | | **FlashList** | FlatList is good, FlashList is better for large lists | `@shopify/flash-list` — drop-in replacement, recycling architecture | | **Large images in lists** | Full-res images decoded on main thread | Use `expo-image` with placeholder + transition, specify dimensions |
Every FlatList should have:
<FlatList
data={items}
keyExtractor={(item) => item.id}
renderItem={renderItem} // Memoised component
getItemLayout={getItemLayout} // If items are fixed height
initialNumToRender={10} // Don't render 100 items on mount
maxToRenderPerBatch={10} // Batch size for off-screen rendering
windowSize={5} // How many screens to keep in memory
removeClippedSubviews={true} // Unmount off-screen items (Android)
/>Native animations run on the UI thread. JS animations block the JS thread and cause jank.
| Pattern | Problem | Fix | |---------|---------|-----| | **Animated API for complex animations** | `Animated` runs on JS thread, blocks interactions | Use `react-native-reanimated` — runs on UI thread | | **Layout animation** | Item appears/disappears with no transition | `LayoutAnimation.configureNext(LayoutAnimation.Presets.easeInEaseOut)` | | **Shared element transitions** | Navigate between screens, element teleports | `react-native-reanimated` shared transitions or `expo-router` shared elements | | **Gesture + animation** | Drag/swipe feels laggy | `react-native-gesture-handler` + `reanimated` worklets — all on UI thread | | **Measuring layout** | `onLayout` fires too late, causes flash | Use `useAnimatedStyle` with shared values for instant response |
import Animated, { useSharedValue, useAnimatedStyle, withSpring } from 'react-native-reanimated';
function AnimatedBox() {
const offset = useSharedValue(0);
const style = useAnimatedStyle(() => ({
transform: [{ translateX: withSpring(offset.value) }],
}));
return (
<GestureDetector gesture={panGesture}>
<Animated.View style={[styles.box, style]} />
</GestureDetector>
);
}| Pattern | Problem | Fix | |---------|---------|-----| | **Expo Router** | File-based routing (like Next.js) for React Native | `app/` directory with `_layout.tsx` files. Preferred for new Expo projects. | | **Heavy screens on stack** | Every screen stays mounted in the stack | Use `unmountOnBlur: true` for screens that don't need to persist | | **Deep linking** | App doesn't respond to URLs | Expo Router handles this automatically. For bare RN: `Linking` API config | | **Tab badge updates** | Badge count doesn't update when tab is focused | Use `useIsFocused()` or refetch on focus: `useFocusEffect(useCallback(...))` | | **Navigation state persistence** | App loses position on background/kill | `onStateChange` + `initialState` with AsyncStorage |
app/ ├── _layout.tsx # Root layout (tab navigator) ├── index.tsx # Home tab ├── (tabs)/ │ ├── _layout.tsx # Tab bar config │ ├── home.tsx │ ├── search.tsx │ └── profile.tsx ├── [id].tsx # Dynamic route └── modal.tsx # Modal route
| Pattern | Problem | Fix | |---------|---------|-----| | **Safe area** | Content under notch or home indicator | `<SafeAreaView>` or `useSafeAreaInsets()` from `react-native-safe-area-context` | | **Keyboard avoidance** | Form fields hidden behind keyboard | `<KeyboardAvoidingView behavior={Platform.OS === 'ios' ? 'padding' : 'height'}>` | | **Platform-specific code** | iOS and Android need different behaviour | `Platform.select({ ios: ..., android: ... })` or `.ios.tsx` / `.android.tsx` files | | **Status bar** | Status bar overlaps content or wrong colour | `<StatusBar style="auto" />` from `expo-status-bar` in root layout | | **Touch targets** | Buttons too small to tap | Minimum 44x44pt. Use `hit
Production workflow skills for Claude Code. Each skill guides Claude through a recipe to produce tangible output — scaffolded projects, generated assets, professional documents, deployed services. Ten plugins of practical, production-oriented skills.
Repo: jezweb/claude-skills
Hit the Cloudflare REST API directly for operations that wrangler and MCP can't handle well. Bulk DNS, custom hostnames, email routing, cache purge, WAF rules,…
Scaffold and deploy Cloudflare Workers with Hono routing, Vite plugin, and Static Assets. Describe project, scaffold structure, configure bindings, deploy. Use…
Generate Drizzle ORM schemas for Cloudflare D1 databases with correct D1-specific patterns. Produces schema files, migration commands, type exports, and…
Cloudflare D1 migration workflow: generate with Drizzle, inspect SQL for gotchas, apply to local and remote, fix stuck migrations, handle partial failures. Use…
Generate database seed scripts with realistic sample data. Reads Drizzle schemas or SQL migrations, respects foreign key ordering, produces idempotent…
Scaffold Hono API routes for Cloudflare Workers. Produces route files, middleware, typed bindings, Zod validation, error handling, and API_ENDPOINTS.md…