projectrules.ai

expo

exporeacttypescriptstate-managementperformance

Description

This rule provides comprehensive best practices and coding standards for Expo projects, covering code organization, performance, security, testing, and common pitfalls to ensure maintainable and high-quality applications.

Globs

**/*.{js,jsx,ts,tsx}
---
description: This rule provides comprehensive best practices and coding standards for Expo projects, covering code organization, performance, security, testing, and common pitfalls to ensure maintainable and high-quality applications.
globs: **/*.{js,jsx,ts,tsx}
---

- **Code Organization and Structure**
  - **Directory Structure:**
    - Adopt a feature-based directory structure, grouping related files (components, hooks, styles, tests) within feature folders.
    - Examples:

      src/
      ├── components/
      │   ├── Button/
      │   │   ├── Button.tsx
      │   │   ├── Button.styles.ts
      │   │   └── Button.test.tsx
      │   └── ...
      ├── screens/
      │   ├── Home/
      │   │   ├── HomeScreen.tsx
      │   │   ├── HomeScreen.styles.ts
      │   │   └── HomeScreen.test.tsx
      │   └── ...
      ├── navigation/
      │   ├── AppNavigator.tsx
      │   └── ...
      ├── services/
      │   ├── api.ts
      │   └── ...
      ├── utils/
      │   ├── helpers.ts
      │   └── ...
      ├── App.tsx
      └── index.tsx

  - **File Naming Conventions:**
    - Use descriptive and consistent names for files and directories.
    - Component files: `ComponentName.tsx` or `ComponentName.js`
    - Style files: `ComponentName.styles.ts` or `ComponentName.styles.js`
    - Hook files: `useHookName.ts` or `useHookName.js`
    - Test files: `ComponentName.test.tsx` or `ComponentName.test.js`
  - **Module Organization:**
    - Group related components, hooks, and utilities into modules.
    - Use `index.ts` (or `index.js`) files to export members from a module for easier importing.
    - Example:

      // src/components/Button/index.ts
      export { default as Button } from './Button';

  - **Component Architecture:**
    - Favor functional components with hooks for managing state and side effects.
    - Separate concerns by creating presentational (UI) and container (logic) components.
    - Use component composition to build complex UIs from smaller, reusable components.
  - **Code Splitting Strategies:**
    - Implement lazy loading for screens or components that are not immediately needed.
    - Utilize `React.lazy` and `Suspense` for dynamic imports.
    - Expo supports dynamic imports; leverage them to reduce initial bundle size.

- **Common Patterns and Anti-patterns**
  - **Design Patterns:**
    - **Higher-Order Components (HOCs):** Use cautiously; prefer hooks or render props for better composability.
    - **Render Props:** A pattern for sharing code between React components using a prop whose value is a function.
    - **Compound Components:** Create components that implicitly share state (e.g., Tabs and Tab).
  - **Recommended Approaches:**
    - Use Expo's APIs for accessing device features (camera, location, notifications) instead of relying on native modules directly where possible.
    - Leverage Expo's managed workflow for a smoother development experience.
  - **Anti-patterns:**
    - Directly manipulating the DOM (use React's state and props instead).
    - Writing complex logic directly within components (extract into hooks or utility functions).
    - Neglecting error handling and edge cases.
  - **State Management:**
    - Use React Context for simple state management.
    - Consider libraries like Zustand, Redux, or Jotai for more complex state management needs.
    - Leverage `useReducer` for managing complex state transitions.
  - **Error Handling:**
    - Implement try-catch blocks to handle potential errors.
    - Use error boundary components to catch errors during rendering.
    - Log errors using a centralized logging service (e.g., Sentry).

- **Performance Considerations**
  - **Optimization Techniques:**
    - Use `React.memo` to prevent unnecessary re-renders of components.
    - Implement `shouldComponentUpdate` (for class components) or `useMemo` and `useCallback` (for functional components) to optimize rendering.
    - Debounce or throttle event handlers to reduce the frequency of updates.
  - **Memory Management:**
    - Avoid creating large arrays or objects in component state if not necessary.
    - Clean up event listeners and timers when components unmount.
    - Release resources when they are no longer needed.
  - **Rendering Optimization:**
    - Virtualize long lists using `FlatList` or `SectionList` to improve scrolling performance.
    - Optimize image sizes and formats to reduce loading times.
    - Use the `useNativeDriver: true` prop in animations for better performance.
  - **Bundle Size Optimization:**
    - Use code splitting to reduce the initial bundle size.
    - Remove unused code and dependencies.
    - Optimize images and other assets.
  - **Lazy Loading:**
    - Implement lazy loading for images and other resources that are not immediately visible.
    - Use the `<Image>` component from `react-native` or `expo-image` with placeholder and loading indicators.

- **Security Best Practices**
  - **Common Vulnerabilities:**
    - Cross-Site Scripting (XSS) - Not typically a risk in React Native/Expo, but be mindful when rendering user-provided content via WebView.
    - Data injection - Protect against SQL or command injection if interacting with backend systems.
    - Insecure data storage - Never store sensitive information (API keys, credentials) directly in the app code.
  - **Input Validation:**
    - Validate user input on both the client and server sides.
    - Use appropriate data types and formats.
    - Sanitize user input to prevent injection attacks.
  - **Authentication and Authorization:**
    - Use secure authentication mechanisms (e.g., OAuth 2.0, JWT).
    - Implement proper authorization to restrict access to sensitive data and functionality.
    - Store authentication tokens securely (e.g., using Expo SecureStore).
  - **Data Protection:**
    - Encrypt sensitive data at rest and in transit.
    - Use HTTPS for all API communication.
    - Avoid storing sensitive information in logs.
  - **Secure API Communication:**
    - Use HTTPS for all API requests.
    - Validate API responses.
    - Implement rate limiting to prevent abuse.

- **Testing Approaches**
  - **Unit Testing:**
    - Write unit tests for individual components, hooks, and utility functions.
    - Use testing libraries like Jest and React Testing Library.
    - Mock dependencies to isolate units of code.
  - **Integration Testing:**
    - Test the interactions between multiple components or modules.
    - Use tools like Detox or Appium for end-to-end testing on real devices or emulators.
  - **End-to-end Testing:**
    - Simulate user interactions to test the entire application flow.
    - Use tools like Detox or Appium for end-to-end testing on real devices or emulators.
  - **Test Organization:**
    - Organize tests in a clear and maintainable structure.
    - Group tests by component or module.
    - Use descriptive names for test cases.
  - **Mocking and Stubbing:**
    - Use mocking to isolate units of code and simulate dependencies.
    - Use stubbing to replace complex or external dependencies with simplified versions.

- **Common Pitfalls and Gotchas**
  - **Frequent Mistakes:**
    - Forgetting to clean up event listeners or timers.
    - Mutating state directly instead of using `setState` or state update functions.
    - Over-rendering components due to unnecessary state updates.
  - **Edge Cases:**
    - Handling different screen sizes and orientations.
    - Dealing with slow network connections or API failures.
    - Managing application state during interruptions (e.g., phone calls).
  - **Version-specific Issues:**
    - Be aware of breaking changes in React Native and Expo SDK updates.
    - Test your application thoroughly after upgrading dependencies.
  - **Compatibility Concerns:**
    - Test your application on different devices and operating systems.
    - Use platform-specific code only when necessary.
  - **Debugging Strategies:**
    - Use the React Native debugger or Chrome DevTools for debugging.
    - Use console.log statements or debugging tools to inspect variables and application state.
    - Use error boundary components to catch and log errors.

- **Tooling and Environment**
  - **Recommended Tools:**
    - VS Code with Expo and ESLint extensions
    - Expo CLI for managing Expo projects.
    - React Native Debugger or Chrome DevTools for debugging.
  - **Build Configuration:**
    - Use environment variables to configure different build environments (development, staging, production).
    - Configure your build process to optimize assets and reduce bundle size.
  - **Linting and Formatting:**
    - Use ESLint with the Airbnb or Standard style guide.
    - Use Prettier to automatically format your code.
    - Configure your editor to automatically run ESLint and Prettier on save.
  - **Deployment:**
    - Use Expo Application Services (EAS) for building and deploying your application.
    - Follow Expo's deployment documentation for best practices.
  - **CI/CD Integration:**
    - Integrate your application with a CI/CD pipeline (e.g., GitHub Actions, CircleCI).
    - Automate testing, linting, and deployment processes.

- **Expo Specific Recommendations**
  - **Use Expo Modules:** Prefer Expo modules for accessing native features over community libraries when available, as they are guaranteed to be compatible and well-maintained within the Expo ecosystem.
  - **EAS Build:**  Use Expo Application Services (EAS) for building native binaries.  This simplifies the build process and handles much of the complexity of native builds.
  - **Expo Updates:** Implement Expo Updates for over-the-air updates.  This allows for quicker iteration and bug fixes without requiring users to download a new version from the app store.
  - **Managed Workflow:** Stick to the managed workflow whenever possible.  It handles much of the native configuration and simplifies development.
  - **Expo SecureStore:** Use `expo-secure-store` to securely store sensitive data like API keys and tokens.
  - **Environment Variables:** Use `.env` files and `expo-constants` to manage environment-specific configurations.
  - **Asset Management:**  Place assets (images, fonts) in the `assets` folder and use the `Image` and `Font` components to load them.

- **TypeScript Best Practices**
  - **Strict Mode:** Enable TypeScript's strict mode (`strict: true` in `tsconfig.json`) for enhanced type safety.
  - **Explicit Types:**  Explicitly define types for function parameters, return values, and variables.
  - **Interfaces vs. Types:** Use interfaces for defining contract between objects, and types for defining data structures.
  - **Utility Types:** Leverage TypeScript's utility types (e.g., `Partial`, `Required`, `Readonly`, `Pick`, `Omit`) for more concise and maintainable code.
  - **Type Guards:** Use type guards to narrow down types within conditional blocks.
  - **Async/Await:** Use `async/await` for asynchronous operations to improve code readability and avoid callback hell.

- **Resources**
  - Expo Documentation: [https://docs.expo.dev/](https://docs.expo.dev/)
  - React Native Documentation: [https://reactnative.dev/](https://reactnative.dev/)
  - Expo JavaScript Style Guide: [https://github.com/expo/expo/blob/main/guides/Expo%20JavaScript%20Style%20Guide.md](https://github.com/expo/expo/blob/main/guides/Expo%20JavaScript%20Style%20Guide.md)