MVVM in Flutter: A Practical Guide, Not the Textbook Definition
FlutterInit’s MVVM is practical: lib/src/data for repos, lib/src/ui for screens and providers — ViewModels without Android textbook baggage.
Stack Configuration — what FlutterInit generates for this guide
When to choose this stack
Use MVVM when you want a clear data/ui split without feature packages or full Clean ceremony.
Textbook MVVM talks about data binding and INotifyPropertyChanged. FlutterInit’s MVVM is simpler: data owns models and repositories; ui owns screens and state objects (Provider, Riverpod, Bloc, MobX, or plain view models). That’s the practical definition we generate.
Layout
lib/src/
data/
models/
repositories/
ui/
auth/ # screens + providers|bloc|stores|…
home/
onboarding/
No features/auth/domain package. Repository interfaces can still live next to implementations under data/.
ViewModels in practice
With Provider selected, auth state is a ChangeNotifier under ui/auth/providers. With Riverpod, you get providers in the same folder slot. With Bloc, ui/auth/bloc. Same screens; different state folder.
Screens should:
- Read state from the ViewModel/provider
- Call methods like
login/signUp - Not touch
AuthServiceor Dio directly
When MVVM is enough
- Apps under ~20 screens
- Beginners graduating from
setState - Appwrite/Firebase auth without multi-team domain politics
When it’s not: shared domain across modules, heavy testing of use cases, or enterprise review culture — move to Clean.
Combo examples: MVVM + Provider + Appwrite, Provider + MVVM + Firebase.
Generate MVVM on /create.
Ready to build?
Generate this project in seconds
FlutterInit scaffolds the entire structure described in this guide — wired up, typed, and ready for flutter run.