LayerKit
Where MVVM meets Clean Architecture
LayerKit is a powerful Flutter framework that combines the best aspects of MVVM (Model-View-ViewModel) pattern with Clean Architecture principles to create a robust, maintainable, and scalable application structure.

π Features
- Clean Project Structure - Organized folder structure that follows both MVVM and Clean Architecture principles
- Feature Generation - CLI tools to quickly scaffold new features with all necessary components
- Project Generation - Quickly bootstrap an entire project with best practices built-in
- Error Handling - Standardized exceptions and failures for consistent error handling
- Configuration System - Flexible configuration for different environments
- Extension Methods - Utility extensions for common types to reduce boilerplate
- UI Utilities - Helper methods for common UI tasks like decorations
- Logging - Development-friendly logging system
π Table of Contents
- Installation
- Project Structure
- Getting Started
- Core Concepts
- Configuration
- Extensions
- Contributing
- License
π Installation
Add LayerKit to your pubspec.yaml:
dependencies:
layer_kit:
Run:
flutter pub get
π Getting Started
Generating a New Project
Create a new Flutter project, then run:
dart run layer_kit --project
This will generate a properly structured project with all the necessary files and configurations.
Generating a New Feature
To add a new feature to your project:
dart run layer_kit --feature feature_name
This command will:
- Create a feature directory in the
srcfolder - Generate all necessary files following MVVM and Clean Architecture principles
- Update routes to include the new feature
π Project Structure
LayerKit organizes your project into a well-defined structure:
lib/
βββ config/ # Configuration files
β βββ data/ # Data-related config
β βββ lang/ # Localization
β βββ routes/ # Routing
β βββ theme/ # Theme configuration
βββ core/ # Core components
β βββ callbacks/ # Callback interfaces
β βββ common/ # Common utilities
β β βββ widgets/ # Reusable widgets
β βββ constants/ # Constants
β βββ extensions/ # Extension methods
β βββ helper/ # Helper methods
β βββ network/ # Network service
β βββ utils/ # Utilities
βββ src/ # Features
β βββ feature1/ # Feature module
β β βββ datasource/ # Data sources
β β β βββ models/ # Data models
β β β β βββ body_models/ # UI display Model (used in screens)
β β β β βββ requests/ # API request models
β β β β βββ response/ # API response models
β β β βββ repo/ # Repository implementation
β β βββ providers/ # Feature providers
β β βββ screens/ # UI screens
β βββ feature2/ # Another feature module
βββ di_container.dart # Dependency Injection imports (part of di main)
βββ di_container.main.dart # di main file - injection of all dependencies
βββ main.dart # Entry point
βοΈ Configuration
LayerKit provides a flexible configuration system through KitConfig:
/// ...code....
@override
Widget build(BuildContext context) {
SystemChrome.setPreferredOrientations([
DeviceOrientation.portraitUp,
DeviceOrientation.portraitDown,
// DeviceOrientation.landscapeRight,
// DeviceOrientation.landscapeLeft,
]);
KitConfig.init(
context: context,
envType: EnvType.development,
defaultRadius: 10,
showApiReqLog: false,
showApiResLog: true,
);
return Consumer<ThemeProvider>(builder: (context, state, _) {
return AppResponsiveTheme( /// for Theme Configuaration [see responsive_theme package on pub.flutter-io.cn]
themeMode: state.theme,
config: ColorConfig(
lightColors: AppColors.light().toThemeColor(),
darkColors: AppColors.dark().toThemeColor(),
),
child: ToastificationWrapper(
child: MaterialApp(
title: AppConsts.appName,
debugShowCheckedModeBanner: false,
/// route config [see flutter_easy_routing package on pub.flutter-io.cn]
navigatorKey: AppRouter.navigatorKey,
onGenerateRoute: (s) => AppRouter.generateRoute(s, SplashScreen()),
scrollBehavior: const StretchScrollBehavior(),
initialRoute: Routes.splash.path,
localizationsDelegates: context.localizationDelegates,
supportedLocales: context.supportedLocales,
locale: context.locale,
theme: state.darkTheme ? ThemeData.dark() : ThemeData.light(),
builder: (context, child) {
return MediaQuery(
data: MediaQuery.of(context).copyWith(textScaler: const TextScaler.linear(1.0)),
child: child ?? SizedBox(),
);
},
),
),
);
});
}
/// ...code....
π§ Core Concepts
MVVM + Clean Architecture
LayerKit combines MVVM pattern with Clean Architecture principles:
- View - Flutter UI components (screens, widgets)
- ViewModel - Business logic and state management
- Model - Data models and repository interfaces
With additional Clean Architecture layers:
- Repositories - Abstract data source interactions and Implementation that access data models
- Data Sources - Concrete implementations of data access - Models, Requests, Responses
ViewModels
ViewModels in LayerKit extend the BaseViewModel class:
class MovieProvider extends BaseViewModel {
final MovieRepo _movieRepo;
final NetworkService _networkService;
MovieProvider({required MovieRepo movieRepo, required NetworkService networkService})
: _movieRepo = movieRepo,
_networkService = networkService;
Future<bool> getData({
required String data1,
required String data2,
bool listen = true,
}) async {
setLoading();
final isNetwork = await _networkService.isConnected;
final isSuccess = await apiCallback(
name: "getData",
isNetwork: isNetwork,
doWhenOnline: () async {
final req = MovieReq(data1: data1, data2: data2);
final res = await _movieRepo.getData(req);
showSnackbar(res.message);
setLoaded();
return res.status;
},
errorListener: (e) {
setError(e.toString());
},
);
if (listen) notifyListeners();
return isSuccess;
}
}
Repositories
Repositories abstract data sources:
abstract interface class MovieRepo {
Future<MovieResponse> getData(MovieReq req);
}
class MovieRepoImpl implements MovieRepo {
final DioClient _dioClient;
MovieRepoImpl({required DioClient dioClient}) : _dioClient = dioClient;
@override
Future<MovieResponse> getData(MovieReq req) async {
return await repoCallback<MovieResponse>(
name: "getData",
callback: () async {
final res = await _dioClient.post(Apis.getData, data: req.toJson());
return MovieResponse.fromJson(res.data ?? {});
},
);
}
}
π οΈ Extensions
LayerKit includes several useful extensions:
// String casing
"hello world".toTitleCase // "Hello World"
"example".firstUpperCased // "Example"
// Time formatting
120.toMMSS // "02 : 00"
3725.toHHMMSS // "01 : 02 : 05"
π€ Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
π License
LayerKit is available under the MIT license. See the LICENSE file for more info.
Created by Nayan Parmar Β© 2025
Libraries
- core/base/base_viewmodel
- core/error/exceptions
- core/error/failures
- core/extensions/extensions
- core/extensions/int_time_formatting_extension
- core/extensions/int_util_extensions
- core/extensions/string_casing_extension
- core/extensions/widget_util_extensions
- core/utils/decoration_utils
- core/utils/devlog
- core/utils/http_overrides
- core/utils/layerkit_config
- core/utils/layerkit_config_provider
- core/utils/layerkit_constants
- core/utils/stretch_scroll_behaviour
- core/utils/utils
- generator/feature_generator
- generator/project_generator
- layer_kit