File Organization
RNCopilot uses path aliases, a strict import order, and barrel files to keep the codebase navigable and refactor-friendly.
Path Aliases
Always use path aliases. Never use relative paths that climb more than one level.
| Alias | Resolves To | Example |
|---|---|---|
@/* | src/* | import { Button } from '@/common/components/Button' |
~/* | app/* | import type { LayoutProps } from '~/types' |
These aliases are configured in both tsconfig.json (TypeScript) and babel.config.js (bundler), so they work in your editor, tests, and at runtime.
// CORRECT
import { Button } from '@/common/components/Button';
import { useAuthStore } from '@/providers/auth/authStore';
import { apiClient } from '@/services/api';
// WRONG -- climbing relative paths
import { Button } from '../../../common/components/Button';Relative imports within the same directory (e.g., ./helpers, ./types) are fine and expected. The rule only prohibits climbing more than one level (../../).
Import Order
Imports are grouped in this exact order, with a blank line between each group:
- React and React Native core
- Expo and third-party libraries
- Internal
@/path alias imports (types last within this group) - Relative imports within the same feature or directory (types last)
import { useState } from 'react';
import { View, Pressable } from 'react-native';
import { useTranslation } from 'react-i18next';
import { StyleSheet } from 'react-native-unistyles';
import { Button } from '@/common/components/Button';
import { useAuthStore } from '@/providers/auth/authStore';
import type { MyProps } from '@/types';
import { localHelper } from './helpers';
import type { LocalType } from './types';Within each group, type imports (import type) come after value imports.
Barrel Files
Every component directory has an index.ts that re-exports the public API:
// src/common/components/Button/index.ts
export { Button } from './Button';
export type { ButtonProps, ButtonVariant, ButtonSize } from './Button.types';Always import from the barrel, never from the implementation file:
// CORRECT
import { Button } from '@/common/components/Button';
// WRONG
import { Button } from '@/common/components/Button/Button';Component Directory Structure
ComponentName/
├── ComponentName.tsx # Required: component implementation
├── ComponentName.types.ts # Optional: props and related types
├── ComponentName.styles.ts # Optional: when styles are substantial
└── index.ts # Required: barrel exportFeature Module Structure
Each feature is a self-contained module under src/features/:
src/features/<feature>/
├── components/ # Feature-specific UI components
├── services/ # API calls (pure async functions, no React)
├── hooks/ # Custom hooks for this feature
├── stores/ # Zustand stores
├── types/ # TypeScript types and interfaces
├── schemas/ # Zod validation schemas
└── constants/ # Feature-level constantsNot every feature needs all subdirectories. Only create the ones you need.
Top-Level Directory Layout
src/
├── common/components/ # 33 shared UI components
├── config/ # Centralized env config with validation
├── features/ # Feature modules (auth, settings, etc.)
├── hooks/ # Global hooks
├── i18n/ # Translation files and config
├── integrations/ # Supabase client
├── providers/ # QueryProvider, auth store
├── services/api/ # Axios client with interceptors
├── theme/ # Semantic tokens, metrics, fonts
├── types/ # Global TypeScript types
└── utils/storage/ # MMKV with typed keys
app/ # Expo Router (file-based routing)
├── _layout.tsx # Root layout with providers
├── +not-found.tsx # 404 screen
└── (main)/(tabs)/ # Tab navigator