К основному содержанию
правило

expo — правило для Cursor: что делает и как установить

Задаёт стандарты разработки мобильных приложений на Expo: структуру папок, Expo Router, TypeScript и правила мемоизации.

Установить в Cursor · Вручную: положить файлы Все способы и платформы ↓
.cursor/rules/expo.mdc
Открыть на GitHub

Что делает expo

Правило регламентирует архитектуру проекта на Expo и React Native. Логика распределяется по папке src/ (компоненты, хуки и сервисы), а навигация строится через файловую структуру каталога app/. В коде запрещаются классовые компоненты. Разрешены только функциональные компоненты и строгий TypeScript.

Для стилизации предписывается использовать StyleSheet.create вместо передачи инлайновых объектов. Асинхронные вызовы обязательно оборачиваются в try/catch, а сбои интерфейса перехватываются глобальным компонентом ErrorBoundary. В части производительности правило требует мемоизацию через React.memo и useCallback.

Клиентские переменные окружения требуют префикса EXPO_PUBLIC_. Секретные ключи API туда помещать нельзя, потому что они попадают в клиентскую сборку: для них нужен EAS Secrets.

Какие задачи решает

  • структурировать проект под файловый роутинг Expo Router
  • заменить инлайновые стили на StyleSheet
  • настроить перехват ошибок через ErrorBoundary и блоки try/catch
  • предотвратить утечку приватных ключей в клиентский бандл

Примеры запросов агенту

  • Создай экран профиля в app/profile/[id].tsx с использованием хуков Expo Router
  • Вынеси инлайновые стили этого компонента в отдельный StyleSheet
  • Добавь асинхронный запрос к API с безопасной обработкой через try/catch

Как установить expo

Вручную: положить файлы

.cursor/rules/expo.mdc

Во frontmatter: description, globs, alwaysApply

По шагам, с командами для каждой платформы: Cursor rules: файлы .mdc, четыре режима и замена .cursorrules

Вопросы о expo

Как установить expo в Cursor?

Создайте файл .cursor/rules/expo.mdc в корне вашего проекта и сохраните в него текст правила.

Что делает правило expo?

Оно заставляет ассистента писать код на Expo по единому стандарту: со строгим TypeScript, навигацией Expo Router, чистыми хуками и мемоизацией.

Как хранить ключи API по этому правилу?

В файл .env с префиксом EXPO_PUBLIC_ вносятся только публичные клиентские адреса. Приватные токены сервисов нельзя хранить на клиенте — для них требуется EAS Secrets.

Исходный текст

expo.mdc · CC0-1.0
---
description: This guide provides definitive, opinionated best practices for building robust, performant, and maintainable cross-platform mobile applications with Expo, leveraging modern React Native patterns and the latest SDK features.
globs: **/*
---
# expo Best Practices

This document outlines the definitive standards for Expo development. Adhere to these guidelines to ensure consistency, performance, and maintainability across our projects.

## 1. Code Organization and Structure

Maintain a clean, scalable project structure.

*   **Root Structure:**
    *   `assets/`: Static assets (images, fonts).
    *   `src/`: All application logic.
        *   `src/components/`: Reusable UI components.
        *   `src/screens/`: Top-level components representing distinct app views.
        *   `src/navigation/`: Navigation configuration (if not using Expo Router's `app/`).
        *   `src/hooks/`: Custom React Hooks.
        *   `src/utils/`: Utility functions, constants.
        *   `src/services/`: API clients, data fetching logic.
*   **Naming Conventions:**
    *   **Files/Folders:** `kebab-case` for directories, `PascalCase` for components, `camelCase` for hooks/utils.
    *   **Components:** `PascalCase` (e.g., `Button.tsx`, `HomeScreen.tsx`).
    *   **Variables/Functions:** `camelCase` (e.g., `userName`, `fetchData`).
    *   **Constants:** `UPPER_SNAKE_CASE` for global constants.

## 2. Component Best Practices

Prioritize functional components, TypeScript, and clear styling.

*   **Functional Components with Hooks:** Always use functional components.
    ❌ BAD:
    ```typescript
    class MyComponent extends React.Component { /* ... */ }
    ```
    ✅ GOOD:
    ```typescript
    const MyComponent: React.FC = () => { /* ... */ };
    ```
*   **TypeScript for Type Safety:** All new code must be in TypeScript.
    ❌ BAD:
    ```javascript
    function greet(name) { return `Hello, ${name}`; }
    ```
    ✅ GOOD:
    ```typescript
    const greet = (name: string): string => `Hello, ${name}`;
    ```
*   **Styling with `StyleSheet`:** Centralize styles for readability and performance.
    ❌ BAD:
    ```typescript
    <Text style={{ fontSize: 16, color: 'blue' }}>Hello</Text>
    ```
    ✅ GOOD:
    ```typescript
    import { StyleSheet, Text } from 'react-native';
    const MyComponent = () => <Text style={styles.text}>Hello</Text>;
    const styles = StyleSheet.create({ text: { fontSize: 16, color: 'blue' } });
    ```

## 3. Navigation with Expo Router

Leverage file-based routing for intuitive navigation.

*   **File-System Based Routing:** Use `app/` directory for routing.
    ❌ BAD: Manual stack/tab navigator setup in a single file for all routes.
    ✅ GOOD:
    ```
    // app/_layout.tsx
    import { Stack } from 'expo-router';
    export default function RootLayout() {
      return <Stack />;
    }

    // app/index.tsx (maps to /)
    export default function HomePage() { /* ... */ }

    // app/profile/[id].tsx (maps to /profile/:id)
    export default function ProfilePage() {
      const { id } = useLocalSearchParams();
      // ...
    }
    ```

## 4. Data & State Management

Manage state efficiently and immutably.

*   **Immutable State Updates:** Always create new objects/arrays when updating state.
    ❌ BAD:
    ```typescript
    const [user, setUser] = useState({ name: 'Alice' });
    user.name = 'Bob'; // Direct mutation
    setUser(user);
    ```
    ✅ GOOD:
    ```typescript
    const [user, setUser] = useState({ name: 'Alice' });
    setUser(prev => ({ ...prev, name: 'Bob' }));
    ```
*   **`useEffect` Dependency Arrays:** Carefully manage dependencies to prevent unnecessary re-renders or infinite loops.
    ❌ BAD:
    ```typescript
    useEffect(() => { fetchData(); }); // Runs on every render
    ```
    ✅ GOOD:
    ```typescript
    useEffect(() => { fetchData(); }, []); // Runs once on mount
    useEffect(() => { saveUser(user); }, [user]); // Runs when user changes
    ```

## 5. Environment Variables

Securely manage environment-specific values.

*   **`EXPO_PUBLIC_` Prefix:** Use `.env` files with `EXPO_PUBLIC_` for client-side variables.
    ❌ BAD: `API_KEY=mysecret` in `.env` and `process.env.API_KEY`. (Exposed in bundle, not automatically injected)
    ✅ GOOD:
    ```
    // .env
    EXPO_PUBLIC_API_URL=https://api.example.com/staging
    ```
    ```typescript
    // In your code
    const apiUrl = process.env.EXPO_PUBLIC_API_URL;
    ```
    > **Warning:** Never store sensitive keys (e.g., private API keys) in `EXPO_PUBLIC_` variables. They are bundled client-side. Use EAS Secrets for server-side secrets.

## 6. Performance Considerations

Optimize for a smooth user experience.

*   **`React.memo` for Pure Components:** Wrap pure functional components to prevent re-renders when props are unchanged.
    ❌ BAD:
    ```typescript
    const MyItem = ({ data }) => { /* ... */ }; // Renders even if data is same object reference
    ```
    ✅ GOOD:
    ```typescript
    const MyItem = React.memo(({ data }) => { /* ... */ });
    ```
*   **`useCallback` and `useMemo`:** Memoize functions and values passed to `React.memo` components or expensive computations.
    ❌ BAD:
    ```typescript
    const handlePress = () => { /* ... */ }; // New function on every render
    <MyItem onPress={handlePress} />
    ```
    ✅ GOOD:
    ```typescript
    const handlePress = useCallback(() => { /* ... */ }, []);
    <MyItem onPress={handlePress} />
    ```
*   **Lazy Loading Screens:** For large apps, lazy load screens with `React.lazy` and `Suspense`.
    ```typescript
    const LazyScreen = React.lazy(() => import('./LazyScreen'));
    // In your navigation or component:
    <Suspense fallback={<LoadingSpinner />}>
      <LazyScreen />
    </Suspense>
    ```

## 7. Error Handling

Implement robust error handling mechanisms.

*   **`try/catch` for Async Operations:** Handle potential errors in asynchronous code.
    ❌ BAD:
    ```typescript
    const fetchData = async () => { await api.get('/data'); };
    ```
    ✅ GOOD:
    ```typescript
    const fetchData = async () => {
      try {
        await api.get('/data');
      } catch (error) {
        console.error('Failed to fetch data:', error);
        // Display user-friendly error message
      }
    };
    ```
*   **Global Error Boundary:** Catch UI errors in React components.
    ```typescript
    // src/components/ErrorBoundary.tsx
    class ErrorBoundary extends React.Component {
      state = { hasError: false };
      static getDerivedStateFromError() { return { hasError: true }; }
      render() {
        if (this.state.hasError) { return <Text>Something went wrong.</Text>; }
        return this.props.children;
      }
    }
    // In App.tsx or _layout.tsx
    <ErrorBoundary><App /></ErrorBoundary>
    ```

## 8. Testing Approaches

Ensure code quality with comprehensive testing.

*   **Unit Tests with Jest & React Testing Library:** Focus on component logic and user interactions. Aim for ≥80% coverage.
    ❌ BAD: No tests, or only shallow rendering tests.
    ✅ GOOD:
    ```typescript
    // src/components/Button.test.tsx
    import { render, fireEvent } from '@testing-library/react-native';
    import Button from './Button';

    test('renders correctly and calls onPress', () => {
      const mockOnPress = jest.fn();
      const { getByText } = render(<Button title="Click Me" onPress={mockOnPress} />);
      fireEvent.press(getByText('Click Me'));
      expect(mockOnPress).toHaveBeenCalledTimes(1);
    });
    ```
*   **Snapshot Testing for UI Components:** Capture UI structure to detect unintended changes.
    ```typescript
    // src/components/Button.test.tsx (continued)
    import renderer from 'react-test-renderer';

    test('renders correctly (snapshot)', () => {
      const tree = renderer.create(<Button title="Test" onPress={() => {}} />).toJSON();
      expect(tree).toMatchSnapshot();
    });
    ```

© sanjeed5 · CC0-1.0 · sanjeed5/awesome-cursor-rules-mdc

Похожие правила IDE

Все правила IDE по теме «Мобильная разработка» →
expo-project-structure expo Скилл задаёт эталонную структуру папок для нового проекта на Expo Router. Помогает разложить экраны, серверные маршруты и компоненты без мусора в корне. CX Codex +1 22 000установок expo-react-native-coder pproenca Скилл с 50 правилами и шаблонами кода для разработки мобильных приложений на Expo и React Native. Пригодится при сборке экранов, навигации и авторизации. CX Codex +1 409установок expo-data-fetching expo Скилл настраивает сетевые запросы, кэширование и обработку ошибок в Expo. Помогает прописать состояния экранов и интеграцию с TanStack Query. CX Codex +1 27 500установок expo-react-native-javascript-best-practices Mindrally Набор правил для разработки мобильных приложений на Expo и React Native с чистым JavaScript. Помогает агенту писать функциональные компоненты, настраивать Expo Router и ускорять рендеринг. CX Codex +1 777установок expo-react-native-typescript Mindrally Скилл задаёт агенту правила разработки мобильных приложений на Expo, React Native и TypeScript: структура файлов, навигация, состояние, тесты. CX Codex +1 2 200установок react-native-expo-cursorrules-prompt-file PatrickJS Правило для Cursor, которое задаёт агенту стек и структуру проекта на React Native с Expo. Пригодится, когда нужно, чтобы код в проекте писался единообразно. ★ 41 028звёзд репо

Из того же набора240

ffmpeg Правило для Cursor, которое задаёт агенту порядок работы с FFmpeg: вызовы через libav*, двухпроходное кодирование и закреплённые сборки в CI. ★ 3 580звёзд репо fastapi Задаёт стандарты разработки на FastAPI: доменную структуру файлов, валидацию через Pydantic и асинхронные зависимости. ★ 3 580звёзд репо fabric-js Правило задаёт практики для fabric-js в JavaScript и TypeScript: модульные импорты, выбор типа canvas и приёмы ускорения рендера. ★ 3 580звёзд репо express Правило для Cursor задаёт структуру Express.js-проекта: слои, конфиг через .env, async/await, валидацию ввода и защитные middleware. ★ 3 580звёзд репо eslint Правило для Cursor с рекомендациями по настройке ESLint в проектах JavaScript и TypeScript. Помогает находить ошибки, проверять возвращаемые значения и поддерживать единый стиль кода. ★ 3 580звёзд репо esbuild Правило для Cursor, которое задаёт агенту порядок работы с esbuild: один конфиг вместо россыпи флагов в package.json. Пригодится, когда сборка уже есть, но её никто не может поддерживать. ★ 3 580звёзд репо emacs Задаёт стандарты написания кода на Emacs Lisp и настройки init.el. Помогает писать чистые пакеты с лексическим связыванием и отложенной загрузкой. ★ 3 580звёзд репо elk-stack Правило задаёт формат логов для ELK: структурированный JSON, общую схему полей и корреляционные ID. Помогает настроить логирование для поиска событий в Elasticsearch и Kibana. ★ 3 580звёзд репо

Спонсоры проекта

Компании, которые помогают держать аналитику открытой