Riverpod + Feature-First + Supabase — Scaling Past Clean Architecture
Riverpod + Feature-First + Supabase keeps feature folders and Supabase auth without paying Clean Architecture ceremony you may not need yet.
Stack Configuration — what FlutterInit generates for this guide
When to choose this stack
Choose this when you already like Riverpod, want Supabase, and prefer feature folders — but Clean’s extra ceremony isn’t buying you anything yet.
Riverpod + Feature-First + Supabase is how you scale past a single-file mess without adopting every Clean Architecture artifact on day one. FlutterInit still gives you lib/src/features/auth/{data,domain,presentation} — same physical shape as Clean in our templates — with Riverpod StateNotifier auth controllers and Supabase wiring.
How this differs from Riverpod + Clean + Firebase
Read the Clean + Firebase guide for the Firebase + Riverpod deep dive. This combo swaps:
- Firebase → Supabase (Postgres,
SUPABASE_URL/SUPABASE_ANON_KEY,onAuthStateChange) - Clean label → Feature-First (same feature folders today; different product default and AGENTS.md framing)
If you’re choosing Feature-First vs Clean as a team decision, see Feature-First vs Clean.
What This Stack Generates
- Feature modules: auth, home, onboarding
- Riverpod
authRepositoryProvider+authControllerProvider(StateNotifier<bool>loading pattern in generated auth logic) - Supabase
AuthServicewith login/signup/logout/stream - go_router + LLM context files
Project Structure
Same Feature-First tree as the Bloc guide: features/auth/data|domain|presentation, with Riverpod files under presentation/providers instead of Bloc.
Riverpod auth controller (generated pattern)
final authRepositoryProvider = Provider<AuthRepository>((ref) {
return AuthRepositoryImpl();
});
final authControllerProvider =
StateNotifierProvider<AuthController, bool>((ref) {
return AuthController(repository: ref.read(authRepositoryProvider));
});
class AuthController extends StateNotifier<bool> {
final AuthRepository _repository;
AuthController({required AuthRepository repository})
: _repository = repository,
super(false);
void login({
required BuildContext context,
required String email,
required String password,
}) async {
state = true;
final result = await _repository.login(email: email, password: password);
state = false;
result.fold(
(failure) { /* toast */ },
(user) { rootContext!.go(AppRoutes.home); },
);
}
}
Screens ref.watch loading state; repositories stay free of widgets.
When to choose this vs Clean + Firebase
| Signal | Pick |
|---|---|
| Already on Supabase / Postgres | This stack |
| Need Firebase Analytics/Crashlytics ecosystem | Clean + Firebase guide |
| Multiple platforms sharing one mental model | Either — enforce via AGENTS.md |
More Supabase detail: Supabase + Riverpod.
Generate it 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.