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
High-Level Architecture Relationships
Core Directory
The core directory is divided into two main sections: domain-based business logic and truly shared utilities:
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:
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:
For UI component best practices and implementation details, refer to the UI Development guides.
Navigation Directory
Navigation configuration for the entire app:
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:
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:
Purpose and Benefits
Documentation → Examples → Implementation Flow:
- Learn: Read comprehensive documentation
- Study: Examine working reference implementations
- 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 (
-
Core domains can import from:
- Shared utilities (
core/shared/*) only
- Shared utilities (
-
UI components can import from:
- Shared utilities (
core/shared/*) only
- Shared utilities (
-
Navigation can import from:
- Shared utilities (
core/shared/*) only
- Shared utilities (
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
Component Structure
All components follow this consistent structure:
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.tsor.test.tsxsuffix
For complete naming guidelines, see the File Naming Conventions.
Do's and Don'ts
Shared Folders Guidelines
- (Do ✅) Place generic, reusable hooks like
useDebounceincore/shared/hooks/ - (Don't ❌) Put domain-specific hooks like
useProductsin shared hooks - (Do ✅) Keep general utilities like
formatDateincore/shared/utils/ - (Don't ❌) Put domain utilities like
calculateProductDiscountin shared utils - (Do ✅) Store cross-domain types like
ApiResponseandAsyncStateincore/shared/types/ - (Don't ❌) Put component-specific types like
ButtonPropsin shared types - these belong co-located with components per the Feature Implementation Decision Tree - (Don't ❌) Duplicate domain types like
Productin shared types
Domain Folders Guidelines
- (Do ✅) Keep domain queries like
useProductsincore/domains/products/hooks.ts - (Do ✅) Store domain models like
Productincore/domains/products/types.ts - (Do ✅) Place domain API calls in
core/domains/products/api.ts - (Consider 🤔) Creating
utils.tsin domain if needed for domain-specific helpers - (Consider 🤔) Adding
queryKeys.tsonly 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
Incorrect Import Patterns
Implementation Considerations
Adding New Domains
- Create folder:
core/domains/[domain-name]/ - Add required files:
api.ts- API service methodstypes.ts- TypeScript interfaceshooks.ts- Query/mutation hooks
- Add optional files as needed:
queryKeys.ts- If many query keysstore.ts- If client state neededevents.ts- If event system needed
- Update barrel exports
Adding New Features
- Create folder:
features/[feature-name]/ - Add standard structure:
screens/- Feature screenscomponents/- Feature componentsnavigation.tsx- Feature routing
- Import from domains for data
- Keep business logic in domains
Migration Strategy
When refactoring existing code:
-
Identify domain boundaries
- Group related API calls
- Extract business types
-
Move to appropriate locations
- Domain logic →
core/domains/ - Generic utilities →
core/shared/ - UI components → Features or
ui/
- Domain logic →
-
Update imports
- Fix all import paths
- Remove circular dependencies
-
Test thoroughly
- Ensure no regressions
- Verify module boundaries