Expo Architecture Guidelines
References
Consult these resources for detailed implementation patterns:
- •./references/folder-structure.md -- Deep dive into the
src/directory organization. - •./references/state-management.md -- Best practices for Jotai atoms and persistence.
- •./references/component-standards.md -- Standards for UI components, styling, and testing.
This document outlines the architectural patterns and technical standards used in this boilerplate.
Architecture Overview
The project follows a modular architecture that separates concerns into clear layers:
- •Presentation Layer: React components and Expo Router screens.
- •State Management Layer: Atoms (Jotai) and Stores.
- •Service Layer: API clients and HTTP abstractions.
- •Data Layer: Models (Types) and Mocks.
- •Utility Layer: Helper functions and cross-cutting concerns.
- •Design System: Theme-based styling and design tokens.
Folder Structure (src/)
- •
app/: Expo Router routes and layouts. Handles file-based navigation. - •
components/: Reusable UI components. Each component should be in its own folder. - •
constants/: Global constants (Environment variables, Storage keys, Strings). - •
hooks/: Custom React hooks for shared logic. - •
models/: TypeScript interfaces and types (Data models). - •
services/: API integration and external service handlers. - •
stores/: Jotai atoms for global and persistent state. - •
styles/: Global styles and styled-component-like abstractions. - •
tasks/: Background tasks and cron-like jobs. - •
theme/: Design tokens (Colors, Spacing, Fonts, Opacity, Border). - •
utils/: Low-level utility functions (Storage, Cache, Matchers).
State Management (Jotai)
We use Jotai for atomic state management.
- •Atoms: Define atoms in
src/stores/. - •Naming: Use
Atomsuffix for atom variables (e.g.,articlesAtom). - •Persistence: Use
atomWithStoragefor data that should persist across app reloads. - •Computed Atoms: Use read-only or read-write atoms for derived state to keep logic out of components.
Example:
typescript
import { atom } from 'jotai';
import { atomWithStorage } from 'jotai/utils';
export const countAtom = atom(0);
export const persistentCountAtom = atomWithStorage('count', 0);
Component Pattern
Each component should follow the "Folder-per-Component" pattern:
code
src/components/MyComponent/ ├── MyComponent.tsx # Implementation ├── MyComponent.styles.ts # StyleSheet definitions ├── MyComponent.stories.tsx # Storybook documentation └── MyComponent.test.tsx # Unit tests (Co-located)
- •Styling: Always separate styles from implementation using
.styles.ts. - •Theme: Use the
theme()function from@/theme/colorsinject colors. - •PascalCase: Folders and implementation files must use PascalCase (e.g.,
AppBar.tsx). - •Co-location: Keep tests and stories next to the code.
Service Layer
- •HTTP Client: Use the abstracted
httputility for base requests. - •API Services: Define business-specific API calls in
src/services/api.ts. - •Mocks: Store mock data in
src/services/mocks/for development and testing.
Routing (Expo Router)
- •Keep
app/files lean. Delegate logic to hooks or stores. - •Use
_layout.tsxfor shared UI (Headers, Providers, Sidebars). - •Use
SlotorStackdepending on the navigation needs.
Code Standards
- •Formatting: We use Biome. Run
pnpm formatto ensure code style compliance. - •TypeScript: Use path aliases (
@/) to avoid deep relative paths (e.g.,../../../../utils). - •Unit Testing:
- •Mandatory for components with logic, hooks, and stores.
- •Follow
EXPO-TEST-SETUP.instructions.md. - •Use
@testing-library/react-native.
Design System
- •Do not use hardcoded colors. Use
theme()fromsrc/theme/colors.ts. - •Use design tokens from
src/theme/(spacing, fonts, etc.) for consistency. - •Prefer
expo-imageover nativeImagefor better caching and performance.