Мобильное приложение на React Native с Claude Code
React Native в 2026 — это Expo SDK 52+. Ты пишешь один код, тестируешь в Expo Go, собираешь через EAS — и получаешь на выходе нативные приложения для iOS и Android. Claude Code с этим управляется отлично, если сразу закрепить стек.
Канал с гайдами и контентом по claude code, выкладываем новости (когда режут лимиты в 10 раз) и какие инструменты через claude реализуем для проектов, канал: https://t.me/claudedevolper
Старт
npx create-expo-app@latest my-app -t cd my-app npx expo install expo-router
Дальше в CLAUDE.md:
Стек - Expo SDK 52, React Native 0.76 - expo-router (file-based navigation) - TanStack Query для API - Zustand для локального state - NativeWind (Tailwind для RN) - TypeScript strict ## Правила - Навигация — только через expo-router, никакого react-navigation напрямую - Стили — NativeWind classes (className), не StyleSheet.create - API — TanStack Query, не fetch в useEffect - Для нативных фич — только expo-* пакеты (не чистый native)
File-based роутинг
// app/_layout.tsx import { Stack } from "expo-router"; import { QueryClient, QueryClientProvider } from "@tanstack/react-query"; const queryClient = new QueryClient(); export default function RootLayout() { return ( ); }// app/(tabs)/_layout.tsx import { Tabs } from "expo-router"; export default function TabsLayout() { return ( ); }
Файлы в app/ автоматически становятся роутами.
Список с pull-to-refresh
// app/(tabs)/index.tsx import { FlatList, Text, View, RefreshControl } from "react-native"; import { useQuery } from "@tanstack/react-query"; import { Link } from "expo-router"; export default function Feed() { const { data = [], refetch, isRefetching } = useQuery({ queryKey: ["products"], queryFn: async () => { const res = await fetch("https://api.example.com/products"); return res.json(); }, }); return ( String(p.id)} refreshControl={} renderItem={({ item }) => ( {item.name} {item.priceCents / 100} ₽ )} /> ); }
Безопасное хранилище
// lib/storage.ts import * as SecureStore from "expo-secure-store"; export const storage = { async setToken(token: string) { await SecureStore.setItemAsync("auth_token", token); }, async getToken() { return SecureStore.getItemAsync("auth_token"); }, async clear() { await SecureStore.deleteItemAsync("auth_token"); }, };
expo-secure-store использует Keychain на iOS и Keystore на Android.
Сборка через EAS
npm i -g eas-cli eas build:configure eas build --platform ios --profile production eas build --platform android --profile production
eas.json:
{ "cli": { "version": ">= 14.0.0" }, "build": { "development": { "developmentClient": true, "distribution": "internal" }, "preview": { "distribution": "internal" }, "production": {} } }
Сборка идёт в облаке Expo — не нужен Mac для iOS.
Подводные камни
- Reanimated требует babel-plugin. Если анимации не работают — проверь babel.config.js.
- NativeWind и темы. Dark mode через useColorScheme() + префиксы dark:.
- Image на Android кэшируется агрессивно. Для динамических URL добавляй ?t=... или используй expo-image.
- fetch без timeout может висеть. Всегда AbortController с таймаутом.
Как попробовать
1. npx create-expo-app@latest 2. Установи Expo Go на телефон 3. npx expo start → скан QR → приложение живое 4. Правишь код в Claude — на телефоне обновляется мгновенно
Канал с гайдами и контентом по claude code, выкладываем новости (когда режут лимиты в 10 раз) и какие инструменты через claude реализуем для проектов, канал: https://t.me/claudedevolper