π§± moarch
A Flutter CLI tool to scaffold Clean Architecture projects with Riverpod β your conventions, your structure, no code generation required.
Features
moarch initβ scaffolds your fulllib/structure in secondsmoarch create feature <n>β generates Clean Architecture layers with an interactive checklist- No
build_runner, nofreezed, noriverpod_annotationβ everything compiles immediately - Providers live at the top of their own file, no separate DI file
- State pattern matches your own style: plain class with safe
copyWith,AsyncNotifier,ref.listen .envand.fvmrcgenerated at project root
Installation
dart pub global activate moarch
Make sure ~/.pub-cache/bin is in your PATH:
# add to .zshrc or .bashrc
export PATH="$PATH:$HOME/.pub-cache/bin"
Quick start
# 1. create your Flutter project
flutter create my_app && cd my_app
# 2. add dependencies to pubspec.yaml (see below)
flutter pub get
# 3. remove the generated main.dart
rm lib/main.dart
# 4. scaffold
moarch init
# 5. create your first feature
moarch create feature auth
Required project dependencies
dependencies:
flutter:
sdk: flutter
flutter_riverpod: ^2.5.1
dio: ^5.4.3
flutter_dotenv: ^5.1.0
flutter_secure_storage: ^9.2.2
Also register .env in your pubspec.yaml assets:
flutter:
assets:
- .env
moarch init
Generates the full project structure:
.env β BASE_URL=
.fvmrc β { "flutter": "stable" }
lib/
βββ main.dart
βββ core/
β βββ constants/
β β βββ app_constants.dart β spacing (4pt grid), text sizes, touch targets, radii, durations
β β βββ api_constants.dart β timeouts only, BASE_URL comes from .env
β βββ errors/
β β βββ app_exception.dart
β βββ network/
β β βββ dio_client.dart β dotenv baseUrl, secure storage auth token, all status codes pass through
β βββ usecases/
β β βββ usecase.dart
β βββ utils/
β βββ extensions.dart β ContextX, StringX, DateTimeX
β βββ logger.dart β single log() function, kDebugMode only
βββ config/
β βββ theme/
β βββ app_theme.dart β useMaterial3, you fill in the rest
βββ shared/widgets/
β βββ app_button.dart β filled / outlined / text variants
β βββ app_loading.dart
β βββ error_view.dart
βββ features/
moarch create feature <n>
Generates Clean Architecture layers with an interactive checklist in the terminal.
moarch create feature auth
moarch create feature user_profile
moarch create feature ProductCatalog # any casing works
moarch create feature auth --all # skip checklist, generate all layers
Checklist β toggle with space, confirm with enter:
Select layers for "Auth":
βΆ [β] Remote Datasource
[ ] Local/Cache Datasource β off by default
[β] Repository (interface + impl)
[ ] Use Cases β off by default
[β] State + Notifier
[β] View
Generated structure:
lib/features/auth/
βββ domain/
β βββ entities/auth_entity.dart
β βββ repositories/auth_repository.dart
β βββ usecases/get_auth.dart β if selected
βββ data/
β βββ datasources/
β β βββ auth_remote_datasource.dart
β β βββ auth_local_datasource.dart β if selected
β βββ models/
β β βββ auth_model.dart
β βββ repositories/
β βββ auth_repository_impl.dart
βββ presentation/
βββ states/auth_state.dart
βββ notifiers/auth_notifier.dart
βββ views/auth_view.dart
βββ widgets/
State pattern used:
class AuthState {
const AuthState({
this.isLoadingAction = false,
this.error,
this.success,
});
final bool isLoadingAction;
final String? error;
final String? success;
AuthState copyWith({
bool? isLoadingAction,
String? error,
String? success,
}) {
return AuthState(
isLoadingAction: isLoadingAction ?? false,
error: error,
success: success,
);
}
}
Error handling in the view uses state.value?.error β your AppException message from the repository β not the AsyncValue error:
ref.listen(authNotifierProvider, (_, next) {
final value = next.value;
if (value?.error != null) {
// show snackbar with value.error
}
});
Customizing moarch
All customization is in lib/src/templates/ β edit the string inside any method to change what gets generated:
| File | Controls |
|---|---|
core_templates.dart |
main.dart, dio_client, constants, errors, utils |
config_templates.dart |
theme |
shared_templates.dart |
app_button, app_loading, error_view |
feature_templates.dart |
entity, model, datasources, repository, state, notifier, view |
After any change, re-activate:
dart pub global activate --source path /path/to/moarch
License
MIT Β© AndrΓ© Montoito