flutter-patterns
Provides production Flutter and Dart 3 patterns covering widget composition, state management choice (Riverpod, BLoC, plain ChangeNotifier), immutability with freezed and records, sealed-class state,
SKILL.mdskills/flutter-patterns/SKILL.md
GitHubFlutter Patterns
Small const widgets, immutable state modelled with sealed types, side effects in a thin layer above the UI, and tests at the widget boundary. Dart 3 features (records, patterns, sealed classes) are assumed.
Always-true conventions (formatting, null safety, sealed types, errors, architecture, mobile
security, test tooling) live in OPM's rules dart/coding-style.md and dart/testing.md
(.claude/rules/opm/dart/ once installed, rules/dart/ in the plugin). This skill keeps the
patterns and worked examples.
When to use
- Starting a Flutter feature and choosing how to structure widgets and state.
- Reviewing Dart for null safety, immutability, async correctness, or rebuild scope.
- Integrating Firebase services in a Flutter app.
- Writing widget, unit, or integration tests.
State management
One approach per app: rule dart/coding-style.md (Architecture).
| Situation | Choice |
|---|---|
| Local, ephemeral UI state (a toggle, a text field, an animation) | StatefulWidget + setState |
| App or feature state, most new apps | Riverpod (code-generated providers) |
| Teams that want explicit event -> state transitions and event logs | BLoC / Cubit |
| Tiny app or package with no dependency budget | ChangeNotifier + ListenableBuilder |
References
- Read references/dart-idioms-and-state.md when handling nulls, modelling state or data classes (sealed, freezed, records), or writing Riverpod or Cubit code.
- Read references/widgets-and-navigation.md when composing widgets, scoping rebuilds, or setting up
go_router. - Read references/async-firebase-and-errors.md when writing async or stream code, using Firebase, or wiring error handling.
- Read references/testing.md when writing unit, widget, golden, or integration tests.
Anti-patterns
user!.namewhereuser?.name ?? defaultwas possible.- Widget-returning private methods instead of widget classes.
setStatefor anything read outside the widget.contextused after anawaitwithout amountedcheck.- Firestore queries or
FirebaseAuth.instancecalls insidebuild. - A
ColumninsideSingleChildScrollViewfor a long list. - Catching
Exceptionin the UI and showinge.toString(). - Tests that pump the whole app to check one widget.
Review checklist
-
dart analyzeclean;flutter testgreen. - State is sealed/immutable; updates create new objects.
- Rebuild scope is minimal;
constused where possible. - Every
awaitin a widget is followed by amountedguard before usingcontext. - Firebase is behind repositories with
withConverter; rules cover every access. - Subscriptions and controllers are disposed.
- New behaviour has a widget or unit test that fails without it.
Related skills
opm:tdd-workflow-flutter testRED/GREEN cycle.opm:verification-before-completion(full gate) -dart analyzeandflutter testas the release gate.