Design Philosophy & Tradeoffs
Honest evaluation of UTA's architectural patterns, design decisions, and guidance for teams considering adoption of our Feature-Domain Hybrid approach.
Design Philosophy & Tradeoffs
Overview
This document provides an honest evaluation of our UTA design philosophy and the specific architectural patterns we've chosen. We believe in transparency about both the benefits and costs of our approach, helping you understand when our Feature-Domain Hybrid strategy aligns with your project needs.
Rather than claiming our architecture fits every scenario, we examine real-world tradeoffs, learning investments, and situations where simpler approaches might be more appropriate. This balanced perspective helps teams make informed decisions about whether our architectural patterns match their specific context and goals.
Purpose & Scope
Target Audience: Technical decision-makers, senior developers, and team leads evaluating architectural approaches for React Native projects, particularly those considering domain-driven design patterns.
What This Document Addresses:
- Our core architectural decisions and the problems they solve
- Honest assessment of learning investment and complexity costs
- Decision framework for evaluating if our patterns fit your project
- Team readiness considerations and adoption strategies
- Alternative architectural approaches for different project types
What This Document Does NOT Cover:
- Step-by-step implementation details (see our Implementation Guides)
- Specific API documentation (see API Integration)
- Development workflow specifics (see Getting Started with UTA and Team Onboarding Checklist)
Prerequisites
To get the most value from this document, we recommend first exploring these foundational resources:
- Core Architecture - This will help you understand our technology stack and foundational patterns
- Domain Architecture Guide - Essential for understanding our domain-driven design approach
- Project Structure - Useful for seeing how our file organization philosophy works in practice
Technical Background: You'll get more from the architectural discussions if you're familiar with React Native development, TypeScript, and modern state management concepts (like the difference between server state and client state).
Technical Foundation: Our architectural patterns work with any modern React Native setup - whether you're using Expo Router + CNG, React Native CLI, or custom configurations. The patterns focus on code organization and business logic, not the underlying technical foundation.
UTA Architectural Design Philosophy
Core Organizational Strategy: Feature-Domain Hybrid
After working with various React Native project structures, we've developed a Feature-Domain Hybrid approach that addresses common pain points we've encountered. This strategy combines the intuitive nature of feature-first organization with the business logic clarity of domain-driven design.
Why We Chose This Approach: Traditional feature-only organization works great initially, but as business logic becomes complex, you end up with logic scattered across UI components. Pure domain-driven approaches can feel abstract for mobile apps. Our hybrid approach gives you the best of both worlds:
Understanding the Layers:
- Features handle everything users see and interact with (screens, navigation, UI state)
- Domains contain pure business logic that could work in any UI context
- Infrastructure provides shared services that both layers can use
This separation means you can change how features look and behave without touching business rules, and you can modify business logic without breaking UI components.
Key Architectural Decisions & Their Benefits
We've made several opinionated decisions based on real-world React Native development challenges we've encountered. Each decision addresses specific pain points that teams commonly face as projects grow:
Feature-Domain Hybrid Organization
- Features for UI: Screen components, navigation, and user-facing logic grouped by user workflow
- Domains for Business Logic: Pure business rules and data models isolated from UI concerns
- Predictable Structure: Teams know exactly where to find and place different types of code
- Scaling Benefits: New features don't require restructuring existing code organization
Problems This Architecture Solves
These patterns emerged from real challenges we've faced in React Native projects. Understanding these pain points helps explain why we've made specific architectural choices:
State Management Confusion
We separate server state (TanStack Query) from client state (Zustand) because mixing them leads to unnecessary complexity, poor performance, and bugs that are hard to debug.
Code Organization Chaos
Our Feature-Domain hybrid provides a predictable structure that team members can understand quickly and that scales naturally as features are added without requiring major refactoring.
Business Logic Coupling
By isolating business rules in domain layers, we ensure that important logic can be tested independently, reused across features, and modified without breaking UI components.
Team Collaboration Friction
Clear, opinionated patterns reduce time spent debating architecture in code reviews and help team members know where to find and place different types of code.
Why This Matters: These aren't theoretical problems - they're based on real experiences from teams scaling React Native applications. Each pattern we've chosen addresses specific pain points that become critical as projects grow beyond initial prototypes.
Architectural Principles
Building on the CNG foundation, the UTA architecture is guided by these principles:
1. Separation of Concerns
- Business Logic: Isolated in domain modules, independent of UI
- Presentation Logic: Contained within feature modules and components
- Infrastructure: Shared utilities and configuration separated from business rules
2. Domain-Driven Design
- Business-Centric Organization: Code structure reflects business domains
- Bounded Contexts: Clear boundaries prevent domain logic bleeding
- Ubiquitous Language: Consistent terminology across code and documentation
3. Unidirectional Data Flow
- Predictable State Changes: Clear patterns for state mutations
- Server State Management: TanStack Query handles API interactions
- Client State Isolation: Zustand manages application-specific state
4. Feature-First Organization
- User-Centric Structure: Features organized around user workflows
- Colocated Code: Related components, screens, and navigation grouped together
- Encapsulation: Features contain their own state and navigation logic
5. Testability by Design
- Dependency Injection: Services can be easily mocked for testing
- Pure Functions: Business logic written as testable pure functions
- Component Isolation: UI components testable independently of business logic
When This Architecture Excels
Complex Business Logic
Domain layer patterns shine when you have sophisticated business rules, calculations, or workflows that need to be consistent across multiple UI contexts.
Growing Development Teams
Clear boundaries and patterns prevent 'stepping on each other's toes' as teams scale from 3-4 developers to 10+ developers working simultaneously.
Long-Term Product Evolution
Feature-Domain hybrid structure accommodates major product pivots and feature additions without requiring large-scale code reorganization.
API-Heavy Applications
TanStack Query patterns excel with complex server state requirements - multiple endpoints, caching strategies, and real-time updates.
Cross-Platform Consistency
Domain layer ensures business logic behaves identically across iOS, Android, and web platforms when using universal React Native approaches.
High Testing Requirements
Clear separation of concerns makes comprehensive testing achievable - unit tests for business logic, integration tests for features.
Honest Assessment of Architectural Tradeoffs
When Our Patterns Create Overhead
Honest Reality: Our architecture is optimized for projects that will grow in complexity over time. If you're building a simple app that will stay simple, this approach may feel like overkill.
Learning Investment You Should Expect
We believe in being upfront about the learning curve. Here's what your team should be prepared for:
- Domain-Driven Design Concepts: Understanding business logic separation is a mindset shift that takes time to internalize
- State Management Patterns: Learning when to use TanStack Query vs. Zustand requires understanding the difference between server and client state
- TypeScript Discipline: Our approach relies heavily on TypeScript for safety, so team members need to be comfortable with comprehensive typing
- Architectural Thinking: Success requires embracing layered architecture concepts rather than putting everything in components
Complexity Considerations
When NOT to Use This Architecture
Key Insight: No architecture fits every scenario. Here's when alternatives might be better choices.
Project Types Where Simpler Approaches Excel
Rapid Prototyping & MVPs
- Timeline: Projects with 2-4 week development cycles
- Scope: Single-feature or proof-of-concept applications
- Alternative: Expo Router with simple folder structure
- Why: Setup overhead exceeds project duration
Technical Constraints
- Legacy Integration: Heavy integration with legacy systems that conflict with modern patterns
- Extreme Performance: Real-time applications with microsecond requirements (rare in mobile apps)
Known Tradeoffs & Their Impact
Development Velocity Tradeoffs
Performance Considerations
- Bundle Size: Additional dependencies increase application size
- Memory Usage: Multiple state management solutions consume more memory
- Initialization Time: Complex setup can slow application startup
- Runtime Overhead: Abstraction layers introduce minimal performance cost
Team Requirements
- Skill Level: Requires developers comfortable with TypeScript and modern React patterns
- Onboarding Time: New team members need 1-2 weeks to become productive
- Maintenance Expertise: Long-term success requires understanding architectural principles
- Decision Making: Teams must commit to following established patterns consistently
Decision Framework
Evaluation Criteria
We've created this framework to help you honestly assess whether our architectural approach makes sense for your specific situation. Rather than advocating for our approach in every case, we want to help you make the right choice for your project:
Project Characteristics
Strong Fit Indicators ✅
- Development timeline exceeding 3 months
- Expected feature count above 10 major features
- Multiple user roles and workflows
- Plans for ongoing feature development
- Integration with multiple backend services
Weak Fit Indicators ❌
- One-time prototype or proof of concept
- Simple CRUD application
- Single-purpose utility app
- Fixed scope with no planned expansion
- Minimal business logic complexity
Decision Tree
Questions to Discuss with Your Team
Team Alignment: These questions can help facilitate productive discussions about whether our approach fits your team's needs and constraints.
Technical Assessment
- How comfortable is our team with TypeScript and modern React patterns?
- Are we planning to integrate with multiple backend services or APIs?
- Do we expect significant growth in features and complexity over time?
- How important is comprehensive testing for this project?
Project Context
- What are our realistic development timeline and team size constraints?
- How do we balance long-term maintainability with time-to-market pressures?
- Do we have stakeholder support for investing in architectural patterns?
- Are we prepared to invest time in team onboarding and learning?
Risk Assessment
- What are the real consequences if our architectural choice doesn't work out?
- How difficult would it be to migrate to a different approach later?
- Do we have the expertise to adapt these patterns to our specific needs?
- How will we maintain architectural consistency as the team grows?
Migration Considerations
Adoption Strategies
New Project Implementation
Recommended Approach: Full adoption from project start
Timeline: 1-2 weeks for initial setup and team training
Steps:
- Clone template and configure for your project
- Conduct team training sessions on architectural patterns
- Implement first feature following established patterns
- Establish code review processes for pattern compliance
- Create project-specific documentation additions
Success Factors:
- Dedicated time for learning and setup
- Team commitment to following patterns
- Clear communication about architectural decisions
Team Preparation Requirements
Technical Skills Development
- TypeScript Proficiency: Essential for taking advantage of type safety
- Modern React Patterns: Hooks, context, and state management
- TanStack Query: Server state management and caching strategies
- Testing Practices: Component testing and integration testing approaches
Process Adaptations
- Code Review Guidelines: Establishing architectural pattern compliance
- Documentation Habits: Maintaining up-to-date architectural documentation
- Feature Planning: Incorporating domain and feature analysis into planning
- Onboarding Processes: Training new team members on architectural patterns
Success Metrics
Short-term Indicators (First 3 months)
- Team comfort level with architectural patterns
- Consistency of pattern implementation across features
- Reduction in time spent on code organization decisions
- Quality of code reviews and architectural discussions
Long-term Indicators (6+ months)
- Developer velocity for new feature implementation
- Reduced time for new team member onboarding
- Decreased bug rates related to state management
- Improved test coverage and reliability
Alternative Architectural Approaches
UTA's Role: UTA provides architectural patterns that can be applied on top of any React Native technical foundation (Expo Router + CNG, React Native CLI, or custom setups).
When to Consider Different Architectural Strategies
Simple Project Organization (Framework Defaults)
- Best For: Prototypes, MVPs, small teams (1-3 developers)
- Benefits: Minimal setup, fast initial development, easy to understand
- Tradeoffs: Limited scalability, no architectural guidance for complexity
Custom Domain-Driven Architecture
- Best For: Enterprise teams with specific architectural requirements, existing DDD expertise
- Benefits: Complete control over patterns, tailored to business context
- Tradeoffs: Requires significant architectural expertise, longer standardization time
UTA's Position as Architectural Layer
Key Understanding: UTA architectural patterns sit above the technical foundation. Whether you use Expo Router + CNG, React Native CLI, or custom configurations, UTA provides the business logic organization and state management strategies.
When UTA Architectural Patterns Are Most Valuable:
- Teams building complex applications that will scale beyond simple CRUD operations
- Projects requiring clear separation between UI logic and business logic
- Organizations prioritizing long-term maintainability and team collaboration
- Applications with sophisticated state management needs (multiple APIs, complex caching)
When Simpler Architectural Approaches Are Better:
- Rapid prototypes and proof-of-concept projects
- Small teams (1-3 developers) building straightforward applications
- Projects with extremely tight deadlines where architectural investment isn't justified
- Teams with strong existing architectural expertise who prefer custom solutions
Related Documents
This document provides the foundation for architectural decision-making. For implementation details and specific guidance, explore these related resources:
Core Architecture Reference
Deep dive into the technical implementation of the UTA architecture patterns and technology stack.
Domain Architecture Guide
Comprehensive guide to implementing domain-driven design patterns for business logic organization.
Project Structure Guide
Detailed explanation of file organization, naming conventions, and folder hierarchy.
Feature Implementation Patterns
Practical patterns for building features that integrate with the architectural foundation.
State Management Architecture
Guide to managing both server state and client state within the architectural framework.
API Integration Patterns
Best practices for integrating with backend services while maintaining architectural boundaries.
This document represents our current understanding of architectural tradeoffs based on real-world experience. As we continue to evolve the architecture based on feedback and new requirements, we'll update this assessment to reflect new insights and learnings.