BLoC Pattern
SkillDev toolsUse when implementing state management with sealed BLoC classes, registering dependency injection with injectable, or setting up GoRouter listeners.
Use BLoC Pattern in Claude, ChatGPT or Ahel Desktop
Free. Sign in, add BLoC Pattern and connect your AI. About a minute.
Also: Claude Code · Cursor · Codex
Then ask your AI: use the BLoC Pattern skill
Details
Instructions available. Your AI can read the instructions. Execution depends on the setup they require.
Account requirements not reviewed. Check the skill instructions before use; Ahel provides instructions and does not run this skill.
No other account needed.
Add Ahel to your AI once: Claude, ChatGPT, Cursor, Claude Code or Codex. Then ask it to use this.
What this skill tells your AI
The instructions your AI receives, as published by dhruvanbhalara/skills in skills/flutter/flutter-bloc/SKILL.md and read by Ahel’s review.
- Sealed States & Events: Always use
sealed classfor both States and Events to ensure exhaustive UI handling and compile-time safety. - Immutability: All States, Events, and Domain Entities MUST be immutable (using
finalandEquatableorfreezed). - Official BLoC Part-Part Of Pattern: Every
_bloc.dartfile MUST include its corresponding_event.dartand_state.dartfiles usingpartdirectives. Each event/state file MUST have apart ofdirective pointing back to the bloc file. This ensures a single library scope and shared private members.// auth_bloc.dart part 'auth_event.dart'; part 'auth_state.dart'; class AuthBloc extends Bloc<AuthEvent, AuthState> { ... } // auth_event.dart part of 'auth_bloc.dart'; // auth_state.dart part of 'auth_bloc.dart'; - Mandatory Directory Structure: Every BLoC feature set MUST reside in its own sub-directory within the
bloc/folder. Flatbloc/directories are STRICTLY prohibited.presentation/bloc/ └── <bloc_name>/ ├── <bloc_name>_bloc.dart ├── <bloc_name>_event.dart └── <bloc_name>_state.dart - Loading State Mandate: ALWAYS emit
Loadingbefore async work, thenSuccessorError. Never skip the loading state. - Concurrency: Use
transformers(e.g.,restartable(),droppable()) for events requiring debouncing (search) or throttling (buttons). - Zero-Logic UI: Widgets MUST NOT contain business logic, orchestration logic, or direct calls to external services. They should ONLY dispatch events and build UI based on BLoC states.
BLoC Widget Usage
BlocBuilderfor local UI rebuilds based on stateBlocListenerfor side effects (navigation, snackbars, dialogs)BlocConsumerwhen both rebuild and side effects are neededcontext.read<Bloc>().add(Event())for dispatching eventscontext.watch<Bloc>().statefor reactive rebuilds (insidebuild()only)
Workflow: Implementing State Management
Follow this sequential workflow when adding or updating a BLoC. Copy the checklist to track progress.
Task Progress
- Step 1: Define Events and States. Ensure they use
Equatablewith correctpropsorfreezed. - Step 2: Implement Async Operations. Verify that all async work follows the
Loading → Success/Errorpattern. - Step 3: Refactor UI. Ensure there is no orchestration or business logic in UI widgets; they must only dispatch events.
- Step 4: Verify Data Sources. Ensure no SDK/API calls exist outside DataSources.
- Step 5: Review Design Tokens. Ensure zero hardcoded colors, spacing, or typography are used.
- Step 6: Format Code. Ensure the code is formatted with
dart format.
Dependency Injection
- Use
injectablefor dependency injection and service location - Standardized Injection:
- Use
@injectablefor screen-specific BLoCs to ensure a fresh instance per screen access. - Use
@lazySingletonfor global or shared BLoCs (e.g.,AuthBloc,ThemeBloc,SettingsBloc,PasswordBloc).
- Use
- Organize blocs logically by feature and ensure strict separation of concerns
Navigation & Routing
- Dynamic Routes: STRICTLY prohibit hardcoded route strings in
GoRouterconfiguration. Use static constants inAppRoutes. - Centralized BLoCs: BLoC providers MUST be injected via
ShellRouteorBlocProviderinapp_router.dartwhen shared across multiple screens or within a feature branch. - No Local Providers: Avoid
BlocProviderin individual screenbuild()methods if the BLoC is needed by a feature set. - Primitive Route Arguments: STRICTLY prohibit passing complex objects (BLoCs, ChangeNotifiers, Entity instances) as route arguments. Pass only primitive IDs/Keys and fetch data in the destination screen using
RepositoryorBlocinjection.
Signals
- GitHub stars
- 30
- Forks
- 4
- Last commit
- Aug 2026
Advanced
- Item type
- skill
- Key
flutter-bloc- Source
- github.com/dhruvanbhalara/skills
github.com/dhruvanbhalara/skills
Related picks
Skill · evanca
The pick for Dartwrite-dart
Skill · cfug
The pick for Dartflutter-auto-route-navigation
Skill · hoangnguyen0403
The pick for Fluttererror-tracking-flutter
Skill · posthog
The pick for Flutterteach
Skill · mattpocock
More in Dev toolsimplement
Skill · mattpocock
More in Dev tools