The Case for Riverpod: Why We Chose It Over Bloc
Our state management journey at Tribar — why we moved from Bloc to Riverpod, how it improved our development velocity, and what we miss.
The Bloc Era
When we started building Flutter apps, Bloc was the obvious choice. It was well-documented, had great tooling, and followed a predictable pattern:
- Events → Bloc → State
- Clear separation of concerns
- Easy to test
But as our apps grew, the boilerplate became painful. Every feature needed:
- An Event class (or multiple)
- A State class
- A Bloc class
- A provider declaration
For a simple counter, that's 4 files. For a real app with 50+ features, it's unsustainable.
Enter Riverpod
Riverpod solved the problems we didn't realize we had:
- No BuildContext needed — Access state anywhere
- Compile-time safety — No runtime ProviderNotFoundException
- Auto-dispose — Memory management without thinking
- Family providers — Parameterized providers without boilerplate
- Code generation — riverpod_generator writes the repetitive parts
Migration Results
After migrating our main app from Bloc to Riverpod:
- 40% less code — Same features, fewer files
- 60% faster provider creation — Code generation handles the pattern
- Easier testing — Override providers in tests without mocking
- Better DX — Hot reload works more reliably
What We Miss
Bloc isn't all bad. We miss:
- BlocListener — Elegant one-shot event handling
- BlocSelector — Fine-grained rebuild control (Riverpod has select, but it's different)
- bloc_test package — Testing blocs was incredibly clean
Our Recommendation
Start with Riverpod for new projects. The reduction in boilerplate and improved developer experience outweigh the learning curve. If you're on Bloc and happy, stay — but if boilerplate frustrates you, Riverpod is worth the switch.