Frontend Guidelines (React Native / Expo)

Frontend Guidelines (React Native / Expo)

Stack

  • React Native with Expo SDK
  • Expo Router (file-based navigation)
  • TypeScript (strict mode)
  • Custom design system (no external UI libraries)
  • i18next for translations (DE, EN minimum)
  • Zustand for global state (keep it simple)
  • TanStack React Query for API state

Project Structure

frontend/
├── app/                    # Expo Router screens (file-based routing)
│   ├── (tabs)/             # Tab navigator
│   ├── (auth)/             # Auth screens
│   └── _layout.tsx         # Root layout
├── components/             # Shared, reusable components
│   ├── ui/                 # Design system primitives (Button, Card, Input)
│   └── {feature}/          # Feature-specific components
├── lib/
│   ├── api/                # API client (typed, generated from OpenAPI)
│   ├── hooks/              # Shared hooks
│   ├── stores/             # Zustand stores
│   └── i18n/               # Translation files
├── constants/              # Design tokens, config
└── assets/                 # Images, fonts

Conventions

  • One component per file
  • Colocate styles with components (StyleSheet.create)
  • Use design tokens from constants/theme.ts
  • Every screen handles: loading, error, empty, and success states
  • Offline-first: cache API responses, show stale data with refresh indicator

TypeScript

  • Strict mode enabled
  • No any type
  • Props interfaces: {ComponentName}Props
  • API types generated from OpenAPI spec

State Management

  • Server state: TanStack React Query (caching, refetching, optimistic updates)
  • Global client state: Zustand (auth, user preferences, theme)
  • Local component state: useState/useReducer
  • Avoid Redux — keep it simple

Internationalization

  • All user-facing strings via i18next
  • Key format: {screen}.{section}.{label} (groups.list.emptyTitle)
  • Default language: German (DE)
  • Required languages: DE, EN
  • Never hardcode strings in components

Accessibility

  • Every interactive element has an accessible label
  • Touch targets: minimum 44x44 points
  • Color contrast: WCAG AA minimum
  • Screen reader support: meaningful labels, not “Button 1”
  • Test with VoiceOver (iOS) and TalkBack (Android)

Performance

  • Lazy load screens (Expo Router does this by default)
  • Use FlatList for long lists (never ScrollView with .map())
  • Optimize images: use WebP, appropriate sizes
  • Minimize re-renders: memoize expensive computations