Overview
Vitu follows a single-file architecture pattern where the entire application is contained inmain.dart (6,698 lines). This is an unconventional but deliberate design choice optimized for rapid development and simplified deployment.
All application code resides in a single file:
lib/main.dart. This includes UI components, business logic, data models, and service integrations.Technology Stack
Core framework for cross-platform development
Modern Material Design 3 theming with custom seed colors
Local-first storage using
hive (^2.2.3) and hive_flutter (^1.1.0)Google Generative AI (
google_generative_ai ^0.4.0) for food analysis and recipe recommendationsKey Dependencies
Application Entry Point
The app initializes Hive boxes before launching the UI:lib/main.dart:21-31
Architecture Pattern: StatefulWidget
Every screen in Vitu uses the StatefulWidget pattern for managing local state and lifecycle:Screen Structure
State Management Strategy
Local State
Each screen manages its own state using
setState(). No global state management library is used.Persistent Data
All persistent data is stored in Hive boxes and retrieved synchronously on screen load.
Navigation Flow
Main Navigation Container
TheVidaPlusApp widget manages bottom navigation with an IndexedStack to preserve state:
lib/main.dart:319-420
IndexedStack keeps all screens alive in memory, preserving scroll positions and local state when switching tabs.Theming System
Vitu implements a dynamic theming system where users can customize:Light or dark mode (stored in UserSettings)
Material 3 seed color for dynamic color schemes (ARGB int)
Custom font family:
null, 'serif', or other system fontsTheme Application
The rootMyApp widget uses a static theme, but individual screens receive theme parameters as constructor props:
lib/main.dart:39-54
Screen Lifecycle
1. Splash Screen
- Displays animated logo with scale and fade transitions
- Checks for existing user session in Hive
- Navigates to either
VidaPlusApporLoginRegisterScreenafter 2.2 seconds
2. Authentication Flow
3. Main Application
Five screens accessible via bottom navigation:- Home (Nutrition)
- Exercise
- Hydration
- Sleep
- Settings
- Food image capture and AI analysis
- Nutritional breakdown with pie chart
- AI-generated recipe recommendations
Key Architectural Decisions
Single-File Design
Advantages
Advantages
- Zero import complexity: No circular dependencies or import management
- Rapid prototyping: All code in one searchable file
- Simplified deployment: Single compilation unit
- Easy debugging: Ctrl+F to find any function/class
Trade-offs
Trade-offs
- Limited scalability: Difficult to maintain beyond ~10k lines
- No code reusability: Hard to extract shared components
- Merge conflicts: High risk in team environments
- IDE performance: Large files can slow down autocomplete
- Testing challenges: Unit testing requires testing entire file
No State Management Library
Decision: Use built-insetState() instead of Provider, Riverpod, or BLoC.
Rationale:
- App has minimal shared state (theme settings only)
- Each screen operates independently
- Data is loaded synchronously from Hive on each screen mount
- Avoids external dependency and learning curve
Local-First with Hive
Decision: Use Hive NoSQL instead of SQLite or cloud database. Rationale:- No internet required for core functionality
- Zero boilerplate (no migrations, schemas)
- Synchronous reads for instant UI updates
- Type-safe with Dart’s dynamic typing
External AI Integration
Decision: Use Google Gemini API instead of on-device ML models. Rationale:- No model training or maintenance required
- Access to state-of-the-art vision and language models
- Handles complex food recognition and recipe generation
- Trade-off: Requires internet and API key management
Code Organization Within main.dart
Despite being a single file, code follows a logical structure:Performance Considerations
Positive
- Hive provides O(1) key-value lookups
IndexedStackavoids rebuilding screens- Charts use efficient fl_chart library
- Images stored on disk, not in memory
Concerns
- Large file size increases compile time
- No code splitting or lazy loading
- All screens loaded at app start
- AI requests block UI thread during analysis
Extension Points
To add new functionality:Migration Path
If the app grows beyond this architecture:- Extract data layer: Move Hive logic to separate repository classes
- Add state management: Introduce Riverpod or BLoC for complex flows
- Modularize screens: Split into feature modules (auth, nutrition, exercise, etc.)
- Add testing: Extract business logic into testable service classes
- Implement CI/CD: Set up automated testing and deployment pipelines
Next Steps
Learn about the Database Schema and AI Integration