Frontend Architecture

Bulletproof React

Our frontend follows the Bulletproof React architecture principles with a focus on feature-based organization and clear separation of concerns. For considered alternatives and decision process, see Frontend Architecture Pattern.

Here's how we structure our codebase:

1. Feature-Based Organization

We organize code by features rather than by file types, following the src/features/ structure:

src/features/
├── auth/                    # Authentication features
├── dark_mode/               # Theme switching functionality
├── map_planning/            # Core map editor
├── maps/                    # Map management
├── nextcloud_integration/   # Nextcloud images integration
├── seeds/                   # Seed library management
└── toasts/                  # Notification system

Each feature contains its own components, hooks, services, and types, making the codebase more modular and easier to maintain.

IMPORTANT: Cross-feature imports are not encouraged. If code needs to be shared between two features, it should be extracted to common code (src/components/, src/hooks/ or src/utils/).

2. Shared Components

Common UI components are placed in src/components/ and designed for reuse across features:

src/components/
├── Button/                # Reusable button components
├── Card/                  # Card layouts
├── Form/                  # Form components and validation
├── Header/                # Application header
├── Layout/                # Page layout components
├── LoadingSpinner/        # Loading states
├── Modals/                # Modal dialogs
└── Slider/                # Input sliders

3. Shared Hooks

Reused business logic or technical utilities are extracted into reusable custom hooks in src/hooks/. Some examples are:

  • useDebouncedSubmit.tsx - Debounced form submissions
  • useDebouncedValue.tsx - Debounced state updates
  • useDimensions.tsx - Responsive design utilities
  • useIsAdmin.tsx - Role-based access control
  • useIsOnline.tsx - Network connectivity detection
  • useKeyHandlers.tsx - Keyboard event management
  • useOrientation.ts - Device orientation handling

4. Shared Utilities

Pure functions and utilities are organized in src/utils/, for example:

  • brushing-utils.ts - Map drawing utilities
  • colors.ts - Color palette and theming
  • enum-utils.ts - Enumeration utilities
  • form-utils.ts - Form-related utilities
  • string-utils.ts - String manipulation utilities

For detailed guideline on creating and organizing common utilities, see Frontend Common Utilities.

5. Type Safety

We achieve type safety in the codebase primarily through automatically generating types shared between frontend and backend. Automatic generation is achieved through the third-partly library typeshare (see Typeshare Research) and integrated into our Makefile commands.

Frontend-only types are organized by features.

  • src/api_types/definitions.ts - Auto-generated types shared between frontend and backend
  • src/features/*/types.ts - Frontend-only types within each feature directory