UTA DevHub
Architecture

Project Structure

Comprehensive reference for the project's directory structure, file organization, and module boundaries with clear shared/domain separation.

Project Structure

Overview

This document provides a comprehensive reference for the project's directory structure, file organization, and module boundaries. It outlines how code is organized following a hybrid architecture that combines feature-based UI organization with domain-based business logic, emphasizing the clear separation between shared utilities and domain-specific code.

Purpose & Scope

This reference is intended for all developers working on the project to understand how code should be organized and where different types of code should be placed. It serves as the definitive guide for project organization with clear rules for shared versus domain-specific code placement.

Directory Structure

Root Structure

project-root/
├── src/                       # Source code
│   ├── core/                  # Domain logic & shared utilities
│   ├── features/              # Feature modules (UI/UX)
│   ├── ui/                    # Shared UI components
│   ├── navigation/            # Navigation configuration
│   ├── App.tsx               # Application entry with providers
│   └── index.js              # Root file
├── assets/                    # Static assets (project root level)
├── android/                   # Android platform files
├── ios/                       # iOS platform files
└── package.json              # Project configuration

High-Level Architecture Relationships

Core Directory

The core directory is divided into two main sections: domain-based business logic and truly shared utilities:

core/
├── domains/                   # Domain-based business logic
│   ├── products/              # Product domain
│   │   ├── api.ts            # Product API service
│   │   ├── types.ts          # Product types (Product, ProductCategory)
│   │   ├── hooks.ts          # Product hooks (useProducts, useProduct)
│   │   └── queryKeys.ts      # Product query keys
│   │
│   ├── users/                # User domain
│   │   ├── api.ts            # User API service
│   │   ├── types.ts          # User types (User, UserProfile)
│   │   ├── hooks.ts          # User hooks (useUser, useUpdateUser)
│   │   └── queryKeys.ts      # User query keys
│   │
│   ├── auth/                 # Authentication domain
│   │   ├── api.ts            # Auth API service
│   │   ├── types.ts          # Auth types (AuthState, LoginRequest)
│   │   ├── hooks.ts          # Auth hooks (useAuth, useLogin)
│   │   ├── store.ts          # Auth state management
│   │   ├── tokenService.ts   # Token management service
│   │   ├── events.ts         # Auth events (sessionExpired)
│   │   └── queryKeys.ts      # Auth query keys
│   │
│   └── [other-domains]/      # Additional domains (orders, payments, etc.)

└── shared/                    # Truly shared, non-domain utilities
    ├── api/
    │   ├── client.ts         # Axios instance with interceptors
    │   └── interceptors.ts   # Request/response interceptors

    ├── query/
    │   └── queryClient.ts    # TanStack Query client config

    ├── hooks/                # Generic React hooks (NO domain logic)
    │   ├── useDebounce.ts    # Debounce hook
    │   ├── useLocalStorage.ts # Local storage hook
    │   ├── useMediaQuery.ts  # Media query hook
    │   └── useTimeout.ts     # Timeout hook

    ├── utils/                # General utilities (NO domain logic)
    │   ├── date.ts           # Date formatting utilities
    │   ├── string.ts         # String manipulation utilities
    │   ├── validation.ts     # Generic validation helpers
    │   └── number.ts         # Number formatting utilities

    ├── types/                # Cross-domain types  
    │   ├── ui.ts             # Cross-domain UI patterns (BaseComponentProps, LoadingState)
    │   ├── global.ts         # Global app types (AppState, Theme)
    │   └── api.ts            # Generic API types (ErrorResponse, Pagination)

    └── styles/               # Global styling
        ├── theme.ts          # Theme constants (colors, spacing)
        ├── typography.ts     # Text styles and fonts
        ├── layout.ts         # Layout utilities
        ├── shadows.ts        # Shadow styles
        └── mixins.ts         # Reusable style patterns

For detailed information on domain-based business logic organization and implementation patterns, see the Domain Architecture Guide.

Features Directory

Features contain UI/UX code organized by user-facing functionality:

features/
├── product-catalog/           # Product browsing feature
│   ├── components/            # Feature-specific components
│   │   └── ProductCard/
│   │       ├── ProductCard.tsx
│   │       ├── styles.ts
│   │       └── index.ts
│   ├── screens/               # Feature screens
│   │   └── ProductListScreen/
│   │       ├── ProductListScreen.tsx
│   │       ├── styles.ts
│   │       └── index.ts
│   ├── navigation.tsx         # Feature navigation setup
│   └── state/                 # Feature-specific UI state
│       └── filterStore.ts     # UI filters state

├── shopping-cart/             # Shopping cart feature
│   ├── components/
│   ├── screens/
│   ├── navigation.tsx
│   └── state/
│       └── cartUIStore.ts     # Cart UI state (drawer open/close)

└── [other-features]/          # Additional features

For more information on implementing features and communication between features and domains, see the Communication Patterns guide.

UI Directory

Shared UI components used across features:

ui/
├── Button/                    # Generic button component
│   ├── Button.tsx
│   ├── styles.ts
│   └── index.ts
├── Card/                      # Generic card component
│   ├── Card.tsx
│   ├── styles.ts
│   └── index.ts
├── Input/                     # Generic input component
│   ├── Input.tsx
│   ├── styles.ts
│   └── index.ts
└── [other-components]/        # Other shared UI components

For UI component best practices and implementation details, refer to the UI Development guides.

Navigation configuration for the entire app:

navigation/
├── RootNavigator.tsx          # Main navigation setup
├── AuthNavigator.tsx          # Auth flow navigation
├── MainNavigator.tsx          # Main app navigation
└── types.ts                   # Navigation type definitions

For more information on navigation configuration and routing strategies, see the related sections in the Core Architecture.

Assets Directory

Static assets organization for brand assets, fonts, animations, and other media:

assets/                        # Project root level
├── brand/                     # Brand assets (logos, illustrations)
│   ├── logos/                 # Company/product logos
│   │   ├── company-logo.svg   # SVG for scalability
│   │   ├── product-logo.svg   # SVG for scalability
│   │   └── partner-logo.png   # PNG with @2x, @3x variants
│   ├── illustrations/         # Marketing/onboarding graphics
│   │   ├── onboarding/
│   │   └── empty-states/
│   └── backgrounds/           # Hero banners, splash screens
├── fonts/                     # Custom font files
│   ├── OpenSans-Regular.ttf
│   ├── OpenSans-Bold.ttf
│   └── OpenSans-Italic.ttf
└── animations/                # Lottie and other animations
    └── loading.json           # Loading animation

Important: UI icons (navigation, actions, status) are managed separately in the UI component system. See the Icon Management for UI icons and the Brand Assets Overview for brand assets.

Reference Implementations Directory

Working examples and demonstrations that mirror the main project structure:

reference-implementations/        # Project root level
├── README.md                    # Overview and usage guide
├── core/                        # Domain and shared utilities examples
│   ├── domains/                 # Business logic implementations
│   │   ├── products/            # Product domain examples
│   │   │   ├── api.example.ts   # Product API service patterns
│   │   │   ├── hooks.example.ts # Product hooks implementations
│   │   │   ├── types.example.ts # Product type definitions
│   │   │   └── README.md        # Domain implementation guide
│   │   ├── users/               # User domain examples
│   │   ├── auth/                # Authentication examples
│   │   └── [other-domains]/     # Additional domain examples
│   │
│   └── shared/                  # Shared utilities examples
│       ├── api/                 # API client patterns
│       │   ├── client.example.ts        # Configured API client
│       │   ├── interceptors.example.ts  # Request/response handling
│       │   └── README.md                # API integration guide
│       ├── hooks/               # Generic hook implementations
│       │   ├── useDebounce.example.ts   # Debounce hook pattern
│       │   ├── useLocalStorage.example.ts # Storage hook pattern
│       │   └── README.md                # Hook development guide
│       ├── utils/               # Utility function examples
│       │   ├── validation.example.ts    # Validation patterns
│       │   ├── formatting.example.ts    # Data formatting
│       │   └── README.md                # Utility development guide
│       └── types/               # Cross-domain type examples
│           ├── api.example.ts           # Generic API types
│           ├── ui.example.ts            # UI pattern types
│           └── README.md                # Type architecture guide

├── features/                    # Feature implementation examples
│   ├── product-catalog/         # Product browsing feature example
│   │   ├── components/          # Feature-specific components
│   │   ├── screens/             # Feature screen implementations
│   │   ├── navigation.example.tsx # Feature navigation patterns
│   │   ├── state.example.ts     # Feature state management
│   │   └── README.md            # Feature implementation guide
│   ├── shopping-cart/           # Shopping cart feature example
│   ├── user-authentication/     # Auth flow feature example
│   └── [other-features]/        # Additional feature patterns

├── ui/                          # UI component implementations
│   ├── foundation/              # Basic building blocks
│   │   ├── Button/              # Button component examples
│   │   │   ├── Button.example.tsx       # Main implementation
│   │   │   ├── Button.variants.tsx      # All visual variants
│   │   │   ├── Button.playground.tsx    # Interactive examples
│   │   │   ├── Button.test.tsx          # Testing patterns
│   │   │   └── README.md                # Component guide
│   │   ├── Input/               # Input component examples
│   │   ├── Card/                # Card component examples
│   │   └── [other-foundation]/  # Additional foundation components
│   │
│   ├── patterns/                # Composed UI patterns
│   │   ├── Modal/               # Modal pattern implementations
│   │   │   ├── Modal.example.tsx        # Basic modal usage
│   │   │   ├── Modal.complex.tsx        # Advanced patterns
│   │   │   ├── Modal.accessibility.tsx  # A11y implementation
│   │   │   └── README.md                # Pattern guide
│   │   ├── Form/                # Form pattern examples
│   │   ├── DataTable/           # Data table implementations
│   │   └── [other-patterns]/    # Additional pattern components
│   │
│   └── business/                # Domain-aware components
│       ├── ProductCard/         # Product display examples
│       │   ├── ProductCard.example.tsx  # Basic implementation
│       │   ├── ProductCard.loading.tsx  # Loading states
│       │   ├── ProductCard.error.tsx    # Error handling
│       │   └── README.md                # Business component guide
│       ├── UserAvatar/          # User display examples
│       └── [other-business]/    # Additional business components

└── docs/                        # Documentation examples
    ├── guides/                  # Implementation guides
    ├── patterns/                # Code pattern examples
    └── best-practices/          # Best practice implementations

Purpose and Benefits

Documentation → Examples → Implementation Flow:

  1. Learn: Read comprehensive documentation
  2. Study: Examine working reference implementations
  3. Implement: Build production features with confidence

Key Benefits:

  • Working Code: All examples are tested and functional
  • Mirror Structure: 1:1 mapping with main project architecture
  • Progressive Learning: From simple examples to complex patterns
  • Template Ready: Copy-paste starting points for new features
  • Best Practices: Demonstrates recommended patterns and approaches

Cross-References: Each implementation includes:

  • Links back to relevant documentation sections
  • GitHub source links for the actual production code
  • Testing examples and patterns
  • Performance considerations
  • Accessibility implementations

For detailed information on using reference implementations effectively, see the Reference Implementations.

Module Boundaries

Shared vs Domain Rules

Import Rules

Why Import Rules Matter

Clear import boundaries help maintain a clean architecture by preventing circular dependencies, ensuring proper separation of concerns, and making the codebase more maintainable and testable.

Allowed Import Patterns

  • Features can import from:

    • Core domains (core/domains/*) for business logic
    • Shared utilities (core/shared/*) for common functions
    • UI components (ui/*) for shared interface elements
    • Navigation (navigation/*) for routing functions
  • Core domains can import from:

    • Shared utilities (core/shared/*) only
  • UI components can import from:

    • Shared utilities (core/shared/*) only
  • Navigation can import from:

    • Shared utilities (core/shared/*) only

Prohibited Import Patterns

  • Features cannot import from:

    • Other features (to prevent feature coupling)
  • Core domains cannot import from:

    • Features (to prevent business logic depending on UI)
    • Other domains (to maintain domain independence)
  • Shared utilities cannot import from:

    • Features (to maintain utility independence)
    • Domains (to keep utilities truly shared and reusable)

Common Import Violations to Avoid

  • Cross-feature imports: Features should not directly import from each other
  • Domain-to-domain imports: Domains should remain independent of each other
  • Shared importing domains: Shared utilities must not depend on domain-specific code
  • Circular dependencies: No module should directly or indirectly depend on itself

Decision Tree for Code Placement

Is this code specific to one business domain?
├─ YES → Place in core/domains/[domain]/
│   ├─ API calls? → api.ts
│   ├─ Data types? → types.ts
│   ├─ React hooks? → hooks.ts
│   └─ Query keys? → queryKeys.ts

└─ NO → Is it used across multiple domains?
    ├─ YES → Place in core/shared/
    │   ├─ React hook? → shared/hooks/
    │   ├─ Utility function? → shared/utils/
    │   └─ Type definition? → shared/types/

    └─ NO → Is it UI-specific?
        ├─ YES → Place in features/[feature]/
        └─ NO → Reconsider architecture

Component Structure

All components follow this consistent structure:

ComponentName/
├── ComponentName.tsx          # Component implementation
├── styles.ts                  # Component-specific styles
├── types.ts                   # Component-specific types (optional)
├── __tests__/                 # Tests directory
│   └── ComponentName.test.tsx # Unit tests
└── index.ts                   # Exports component

File Naming Conventions

This project follows strict file naming conventions to ensure consistency:

  • Components: PascalCase (e.g., Button.tsx, ProductCard.tsx)
  • Hooks: camelCase with "use" prefix (e.g., useAuth.ts, useDebounce.ts)
  • Domain files: lowercase descriptive (e.g., api.ts, types.ts)
  • Utilities: lowercase by category (e.g., date.ts, string.ts)
  • Features: kebab-case folders (e.g., product-catalog/)
  • Tests: .test.ts or .test.tsx suffix

For complete naming guidelines, see the File Naming Conventions.

Do's and Don'ts

Shared Folders Guidelines

  • (Do ✅) Place generic, reusable hooks like useDebounce in core/shared/hooks/
  • (Don't ❌) Put domain-specific hooks like useProducts in shared hooks
  • (Do ✅) Keep general utilities like formatDate in core/shared/utils/
  • (Don't ❌) Put domain utilities like calculateProductDiscount in shared utils
  • (Do ✅) Store cross-domain types like ApiResponse and AsyncState in core/shared/types/
  • (Don't ❌) Put component-specific types like ButtonProps in shared types - these belong co-located with components per the Feature Implementation Decision Tree
  • (Don't ❌) Duplicate domain types like Product in shared types

Domain Folders Guidelines

  • (Do ✅) Keep domain queries like useProducts in core/domains/products/hooks.ts
  • (Do ✅) Store domain models like Product in core/domains/products/types.ts
  • (Do ✅) Place domain API calls in core/domains/products/api.ts
  • (Consider 🤔) Creating utils.ts in domain if needed for domain-specific helpers
  • (Consider 🤔) Adding queryKeys.ts only if you have > 3 query keys

Feature Folders Guidelines

  • (Do ✅) Import data from domain hooks (core/domains/*/hooks.ts)
  • (Do ✅) Use shared utilities from core/shared/*
  • (Do ✅) Keep UI state local to features
  • (Don't ❌) Import from other features
  • (Don't ❌) Implement business logic in features

General Guidelines

  • (Do ✅) Use index.ts files for clean exports
  • (Do ✅) Maintain consistent naming conventions
  • (Do ✅) Write tests alongside components
  • (Don't ❌) Create circular dependencies
  • (Don't ❌) Mix concerns (UI with business logic)

Examples

Correct Import Patterns

// In features/product-catalog/screens/ProductList.tsx
import { useProducts } from '@/core/domains/products'; // ✅ Domain hook
import { formatCurrency } from '@/core/shared/utils'; // ✅ Shared utility  
import { Button } from '@/ui/foundation/Button'; // ✅ Shared UI component
 
// In core/domains/products/api.ts
import { apiClient } from '@/core/shared/api'; // ✅ Shared API client
import type { Product } from './types'; // ✅ Same domain type
 
// In core/shared/hooks/useDebounce.ts
import { useState, useEffect } from 'react'; // ✅ Only React imports
// No domain imports! ✅

Incorrect Import Patterns

// In features/product-catalog/screens/ProductList.tsx
import { CartItem } from '@/features/shopping-cart/components'; // ❌ Cross-feature
 
// In core/shared/utils/product.ts
import { Product } from '@/core/domains/products'; // ❌ Domain in shared
 
// In core/domains/products/hooks.ts
import { useDebounce } from '@/core/shared/hooks'; // ✅ Fixed: Use shared hook

Implementation Considerations

Adding New Domains

  1. Create folder: core/domains/[domain-name]/
  2. Add required files:
    • api.ts - API service methods
    • types.ts - TypeScript interfaces
    • hooks.ts - Query/mutation hooks
  3. Add optional files as needed:
    • queryKeys.ts - If many query keys
    • store.ts - If client state needed
    • events.ts - If event system needed
  4. Update barrel exports

Adding New Features

  1. Create folder: features/[feature-name]/
  2. Add standard structure:
    • screens/ - Feature screens
    • components/ - Feature components
    • navigation.tsx - Feature routing
  3. Import from domains for data
  4. Keep business logic in domains

Migration Strategy

When refactoring existing code:

  1. Identify domain boundaries

    • Group related API calls
    • Extract business types
  2. Move to appropriate locations

    • Domain logic → core/domains/
    • Generic utilities → core/shared/
    • UI components → Features or ui/
  3. Update imports

    • Fix all import paths
    • Remove circular dependencies
  4. Test thoroughly

    • Ensure no regressions
    • Verify module boundaries