By Abdelrahman Saed — Senior Mobile Engineer. Last updated: 2026-08-10.
BLoC (Business Logic Component) is a reactive state management pattern for Flutter that separates business logic from presentation using streams. Events go in, states come out, and the UI never touches business logic directly — it reacts to state changes the way it reacts to any data source.
BLoC converts a stream of events (user actions, lifecycle signals, data fetches) into a stream of states (the data the UI renders). The bloc itself is a pure function — the same events in the same order always produce the same states — which makes it trivially testable.
The data flow is strictly one-directional:
Widget → Event → BLoC → State → Widget
A widget dispatches an event when the user interacts with it. The bloc receives the event, runs the business logic (calling repositories, transforming data, enforcing rules), and emits a new state. The widget rebuilds with the new state via StreamBuilder or BlocBuilder.
Here is a minimal counter bloc:
// Events
abstract class CounterEvent {}
class IncrementPressed extends CounterEvent {}
class DecrementPressed extends CounterEvent {}
// States
abstract class CounterState {}
class CounterInitial extends CounterState {
final int count;
CounterInitial(this.count);
}
// Bloc
class CounterBloc extends Bloc<CounterEvent, CounterState> {
CounterBloc() : super(CounterInitial(0)) {
on<IncrementPressed>((event, emit) {
emit(CounterInitial((state as CounterInitial).count + 1));
});
on<DecrementPressed>((event, emit) {
emit(CounterInitial((state as CounterInitial).count - 1));
});
}
}
At iStoria (5M+ users, 50+ modules), every feature follows the same pattern: events define every user intent, states define every UI configuration, and the bloc mediates. The result is that a new engineer can read any feature's event/state classes and understand its full behaviour without touching the UI layer.
Choose BLoC when:
bloc_concurrency and hybrid_bloc logging let you replay any state transition.Skip BLoC when:
Cubit is a simplified version of BLoC that replaces event classes with direct method calls. Instead of dispatching an IncrementPressed event, you call increment(). Cubit is better for simple state; BLoC is better when you need the event trail or complex event-to-state transformations.
Yes. BLoC remains the most battle-tested state management pattern for large Flutter apps. It is the default at companies like iStoria (5M+ users) and is actively maintained with the flutter_bloc package. For new apps, Cubit (BLoC without events) is often a better starting point, migrating to full BLoC when event granularity is needed.
Yes — BLoC pairs naturally with offline-first architectures. The bloc receives events from the UI, calls repository methods (which read from the local database first), and emits state. Whether the data came from the local Drift database or a PowerSync sync round-trip is transparent to the bloc.
Available for hire. Abdelrahman Saed is a Senior Mobile Engineer (Flutter) — open to full-time, fractional, contract, or advisory work. Hire me →
Book a 20-minute call · Download the CV (PDF) · See how I work