Skip to content

About

A production-ready Flutter starter kit using **MVVM architecture** with **Provider** for state management and **GetIt** for dependency injection. Built to jumpstart new projects without creating everything from scratch.

Resources

Stars

1 star

Watchers

0 watching

Forks

Latest commit

 

History

1 Commit

Folders and files

Repository files navigation

Flutter Clean Architecture Starter Kit (Provider)

A production-ready Flutter starter kit using MVVM architecture with Provider for state management and GetIt for dependency injection. Built to jumpstart new projects without creating everything from scratch.

🏗️ Architecture

┌─────────────────────────────────────────────────────────┐
│                    Presentation Layer                    │
│  (Pages, Widgets)                                        │
│  Uses ChangeNotifierProvider / Consumer / Selector       │
└──────────────────────┬──────────────────────────────────┘
                       │ reads / notifies
┌──────────────────────▼──────────────────────────────────┐
│                    ViewModel Layer                        │
│  (ChangeNotifier)                                        │
│  Business logic, state management, navigation            │
└──────────────────────┬──────────────────────────────────┘
                       │ calls
┌──────────────────────▼──────────────────────────────────┐
│                    Repository Layer                      │
│  (Abstract Repo + RepoImpl)                              │
│  Returns Either<Failure, GenericApiModel<T>>             │
└──────────────────────┬──────────────────────────────────┘
                       │ uses
┌──────────────────────▼──────────────────────────────────┐
│                    Data Layer                             │
│  (ApiClient, CacheService, SharedPreferences)            │
└─────────────────────────────────────────────────────────┘

📁 Project Structure

flutter_clean_arch_starter/
├── lib/
│   ├── core/                          # Core app files
│   │   ├── api/
│   │   │   ├── api_client.dart        # Abstract API client (post/get with callbacks)
│   │   │   └── http_client_manager.dart  # HTTP wrapper with timeout
│   │   ├── common_models/
│   │   │   └── generic_api_model.dart # Generic API response wrapper<T>
│   │   ├── exceptions/
│   │   │   ├── api_exception.dart     # Exception wrapper
│   │   │   └── api_failure.dart       # Failure hierarchy (Equatable)
│   │   ├── utils/
│   │   │   ├── loading_utils.dart     # Full-screen loader
│   │   │   ├── size_utils.dart        # Sizer extensions
│   │   │   ├── utils.dart             # Common utilities
│   │   │   └── validation_utils.dart # Form validators
│   │   ├── api_consts.dart            # API URLs & endpoints
│   │   ├── app_assets.dart            # Asset path constants
│   │   ├── app_export.dart            # Barrel exports
│   │   ├── app_state.dart             # Global app state (auth, tokens)
│   │   ├── cache_consts.dart          # SharedPreferences keys
│   │   ├── dependencies.dart         # GetIt DI setup
│   │   └── enums.dart                 # App-wide enums
│   ├── extensions/
│   │   ├── context_extensions.dart    # Theme, colors, navigation
│   │   ├── string_extensions.dart     # String manipulations
│   │   └── widget_extensions.dart     # Padding, center, expand
│   ├── features/                      # Feature modules (MVVM)
│   │   └── authentication/            # Example feature
│   │       ├── authentication_repo.dart       # Abstract + Impl
│   │       └── authentication_view_model.dart # ChangeNotifier
│   ├── presentation/                  # UI pages
│   │   ├── authentication/
│   │   │   └── login_page.dart        # Login screen
│   │   └── home/
│   │       └── home_page.dart         # Home screen
│   ├── routes/
│   │   └── app_routes.dart            # Named routes
│   ├── services/                      # App services (DI)
│   │   ├── analytics_service.dart     # Analytics (no-op impl)
│   │   ├── cache_service.dart         # SharedPreferences wrapper
│   │   ├── dialog_service.dart        # Dialogs, bottom sheets, snackbars
│   │   ├── error_handler_service.dart # Failure → user action mapping
│   │   ├── logger_service.dart        # Logger wrapper
│   │   └── navigation_service.dart    # Navigator key + navigation
│   ├── theme/
│   │   ├── app_theme.dart             # Light & dark ThemeData
│   │   └── colors.dart                # Color palette + dark mode
│   ├── widgets/                       # Reusable widgets
│   │   ├── custom_button.dart         # Elevated/Outlined button
│   │   ├── custom_text_field.dart     # Form text field
│   │   └── loading_widget.dart        # Loader + Shimmer
│   └── main.dart                      # Entry point
├── assets/
│   ├── animations/lottie/             # Lottie JSON files
│   ├── fonts/                         # Font files (Poppins)
│   ├── langs/                         # Localization JSON
│   │   ├── en-US.json
│   │   └── ar-SA.json
│   ├── png/                           # PNG images
│   └── svg/                           # SVG images
├── test/
├── pubspec.yaml
├── analysis_options.yaml
├── .gitignore
└── README.md

🚀 Getting Started

1. Prerequisites

  • Flutter SDK >= 3.6.0
  • Dart SDK >= 3.6.0

2. Install Dependencies

cd flutter_clean_arch_starter
flutter pub get

3. Generate Platform Folders

This starter kit contains only the lib/ and assets/ structure. Generate the android/ and ios/ folders:

flutter create --org com.yourcompany --project-name flutter_clean_arch_starter .

4. Configure API

Edit lib/core/api_consts.dart:

  • Set appEnvironmentType to dev, uat, staging, or prod
  • Update baseUrl and endpoint paths

5. Run the App

flutter run

📦 Included Dependencies

Category Package Purpose
State Management provider ChangeNotifier-based state management
DI get_it Service locator / dependency injection
Networking http HTTP client
Network Check connectivity_plus Internet connectivity check
Storage shared_preferences Local key-value storage
Functional dartz Either<Failure, T> for error handling
Value Equality equatable Failure class equality
Logging logger Pretty-printed console logs
Localization easy_localization i18n with JSON files
Images cached_network_image Image caching
SVG flutter_svg SVG rendering
Responsive sizer Screen-responsive sizing
UI shimmer Loading placeholders
UI auto_size_text Auto-scaling text
UI fluttertoast Toast messages
UI flutter_rating_bar Star ratings
Utilities url_launcher Open external links
Utilities path_provider File system paths
Utilities device_info_plus Device info

🧩 Adding a New Feature

Follow the MVVM pattern demonstrated in authentication:

1. Create the Feature Folder

lib/features/your_feature/
├── your_feature_repo.dart
├── your_feature_view_model.dart
└── models/
    ├── request/
    └── response/

2. Create the Repository

abstract class YourFeatureRepo {
  Future<Either<Failure, GenericApiModel<dynamic>>> getData();
}

class YourFeatureRepoImp implements YourFeatureRepo {
  final ApiClient apiClient;
  final LoggerService loggerService;

  YourFeatureRepoImp({required this.apiClient, required this.loggerService});

  @override
  Future<Either<Failure, GenericApiModel<dynamic>>> getData() async {
    // Call apiClient.post() and return Either
  }
}

3. Create the ViewModel

class YourFeatureViewModel extends ChangeNotifier {
  final YourFeatureRepo repo;
  final ErrorHandlerService errorHandlerService;

  YourFeatureViewModel({required this.repo, required this.errorHandlerService});

  // Add state, methods, notifyListeners()
}

4. Register in GetIt

In lib/core/dependencies.dart:

getIt.registerLazySingleton<YourFeatureRepo>(
  () => YourFeatureRepoImp(apiClient: getIt(), loggerService: getIt()),
);

getIt.registerLazySingleton<YourFeatureViewModel>(
  () => YourFeatureViewModel(repo: getIt(), errorHandlerService: getIt()),
);

5. Create the Page

class YourFeaturePage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return ChangeNotifierProvider<YourFeatureViewModel>(
      create: (_) => getIt<YourFeatureViewModel>(),
      child: Scaffold(
        body: Consumer<YourFeatureViewModel>(
          builder: (context, vm, _) {
            // Build UI
          },
        ),
      ),
    );
  }
}

6. Add Route

In lib/routes/app_routes.dart:

static const String yourFeaturePage = '/yourFeaturePage';

// In routes map:
yourFeaturePage: (context) => YourFeaturePage(),

🔑 Key Patterns

Error Handling with dartz

final result = await repo.getData();

result.fold(
  (failure) => errorHandlerService.handleError(failure: failure),
  (apiResponse) => // Handle success
);

Theme-Aware Colors

// Using BuildContext extension (recommended):
Container(color: context.primaryColor);
Text('Hello', style: TextStyle(color: context.textColor));

// Using static getters:
Container(color: AppColors.primaryColor);

Responsive Sizing

// Using Sizer extensions:
SizedBox(height: 2.h);  // 2% of screen height
Text('Hello', style: TextStyle(fontSize: 14.sp));

Navigation from ViewModel

navigationService.pushNamed(AppRoutes.yourFeaturePage);
navigationService.pushNamedAndRemoveUntil(AppRoutes.landingScreen, (r) => false);

🌍 Localization

Add translations to assets/langs/en-US.json and ar-SA.json:

{
  "yourKey": "Your translation"
}

Generate locale keys (optional):

flutter pub run easy_localization:generate -S assets/langs -f keys -o locale_keys.g.dart

📄 License

This project is open source. Feel free to use it for your projects.

About

A production-ready Flutter starter kit using **MVVM architecture** with **Provider** for state management and **GetIt** for dependency injection. Built to jumpstart new projects without creating everything from scratch.

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages