flutter_gen_cat 1.0.0
flutter_gen_cat: ^1.0.0 copied to clipboard
FlutterGenCat is a CLI scaffold tool that brings MVVM and Clean Architecture into Flutter projects. Starts from plain MVVM and grows into Clean Architecture one flag at a time.
Example: scaffolding a feature #
A walkthrough of one command and every file it produces.
flutter_gen_cat create counter
That is the default: plain MVVM on Provider, in the flat layout. Six files,
184 lines, no build_runner step and no generated-code markers to work around.
lib/features/counter/
model/ counter_model.dart 32 lines
repository/ counter_repository.dart 14 lines interface
counter_repository_impl.dart 23 lines implementation
view_model/ counter_view_model.dart 45 lines
view/ counter_view.dart 36 lines
di/ counter_injector.dart 34 lines
The files #
Each page below shows one layer in full, explains what it is responsible for, and points at the lines you are expected to change.
| Layer | What it holds | |
|---|---|---|
| 1 | Model | The serializable data class, with JSON and value equality |
| 2 | Repository | The contract, and the implementation behind it |
| 3 | View model | Loading / error / data state, free of widgets |
| 4 | View | The widget bound to that state |
| 5 | Injector | Dependency wiring for the whole feature |
Mounting it #
Provider and BLoC features come with an injector that wraps a subtree:
MaterialApp(
home: CounterInjector.provide(child: const CounterView()),
)
Riverpod declares its providers at the top level instead, so a ProviderScope
at the app root is all it needs:
ProviderScope(
child: MaterialApp(home: CounterView()),
)
Growing the feature #
The same feature can gain Clean Architecture layers later, one at a time:
# A use case between the view model and the repository
flutter_gen_cat add usecase reset_counter --feature counter
FlutterGenCat reads counter off disk first. Because that feature is flat and
has no entity, the use case lands at usecase/reset_counter_use_case.dart and
speaks in CounterModel:
class ResetCounterUseCase {
const ResetCounterUseCase(this._repository);
final CounterRepository _repository;
Future<CounterModel> call() => _repository.fetch();
}
Had the feature been created with --clean, the same command would have
written to domain/usecase/ and returned CounterEntity instead — without you
repeating any flags.
The full Clean Architecture slice #
flutter_gen_cat create checkout --clean -s riverpod
The six files above become ten, grouped into the three layers:
lib/features/checkout/
data/
model/ checkout_model.dart
mapper/ checkout_mapper.dart <- new
datasource/ checkout_remote_data_source.dart <- new
repository/ checkout_repository_impl.dart
domain/
entity/ checkout_entity.dart <- new
repository/ checkout_repository.dart
usecase/ get_checkout_use_case.dart <- new
presentation/
view_model/ checkout_view_model.dart
view/ checkout_view.dart
di/ checkout_injector.dart
The four new files are what the --with-entity, --with-usecase and
--with-datasource flags add individually. Nothing forces you to take all of
them at once.
See the main README for the full command reference.