Loading source
Pulling the file list, source metadata, and syntax-aware rendering for this listing.
Source from repo
Build cross-platform Flutter 3 apps with Riverpod/Bloc state management, GoRouter navigation, and performance optimization.
Files
Skill
Size
Entrypoint
Format
Open file
Syntax-highlighted preview of this file as included in the skill package.
SKILL.md
1---2name: flutter-expert3description: Use when building cross-platform applications with Flutter 3+ and Dart. Invoke for widget development, Riverpod/Bloc state management, GoRouter navigation, platform-specific implementations, performance optimization.4license: MIT5metadata:6author: https://github.com/Jeffallan7version: "1.1.0"8domain: frontend9triggers: Flutter, Dart, widget, Riverpod, Bloc, GoRouter, cross-platform10role: specialist11scope: implementation12output-format: code13related-skills: react-native-expert, test-master, fullstack-guardian14---1516# Flutter Expert1718Senior mobile engineer building high-performance cross-platform applications with Flutter 3 and Dart.1920## When to Use This Skill2122- Building cross-platform Flutter applications23- Implementing state management (Riverpod, Bloc)24- Setting up navigation with GoRouter25- Creating custom widgets and animations26- Optimizing Flutter performance27- Platform-specific implementations2829## Core Workflow30311. **Setup** — Scaffold project, add dependencies (`flutter pub get`), configure routing322. **State** — Define Riverpod providers or Bloc/Cubit classes; verify with `flutter analyze`33- If `flutter analyze` reports issues: fix all lints and warnings before proceeding; re-run until clean343. **Widgets** — Build reusable, const-optimized components; run `flutter test` after each feature35- If tests fail: inspect widget tree with Flutter DevTools, fix failing assertions, re-run `flutter test`364. **Test** — Write widget and integration tests; confirm with `flutter test --coverage`37- If coverage drops or tests fail: identify untested branches, add targeted tests, re-run before merging385. **Optimize** — Profile with Flutter DevTools (`flutter run --profile`), eliminate jank, reduce rebuilds39- If jank persists: check rebuild counts in the Performance overlay, isolate expensive `build()` calls, apply `const` or move state closer to consumers4041## Reference Guide4243Load detailed guidance based on context:4445| Topic | Reference | Load When |46|-------|-----------|-----------|47| Riverpod | `references/riverpod-state.md` | State management, providers, notifiers |48| Bloc | `references/bloc-state.md` | Bloc, Cubit, event-driven state, complex business logic |49| GoRouter | `references/gorouter-navigation.md` | Navigation, routing, deep linking |50| Widgets | `references/widget-patterns.md` | Building UI components, const optimization |51| Structure | `references/project-structure.md` | Setting up project, architecture |52| Performance | `references/performance.md` | Optimization, profiling, jank fixes |5354## Code Examples5556### Riverpod Provider + ConsumerWidget (correct pattern)5758```dart59// provider definition60final counterProvider = StateNotifierProvider<CounterNotifier, int>(61(ref) => CounterNotifier(),62);6364class CounterNotifier extends StateNotifier<int> {65CounterNotifier() : super(0);66void increment() => state = state + 1; // new instance, never mutate67}6869// consuming widget — use ConsumerWidget, not StatefulWidget70class CounterView extends ConsumerWidget {71const CounterView({super.key});7273@override74Widget build(BuildContext context, WidgetRef ref) {75final count = ref.watch(counterProvider);76return Text('$count');77}78}79```8081### Before / After — State Management8283```dart84// ❌ WRONG: app-wide state in setState85class _BadCounterState extends State<BadCounter> {86int _count = 0;87void _inc() => setState(() => _count++); // causes full subtree rebuild88}8990// ✅ CORRECT: scoped Riverpod consumer91class GoodCounter extends ConsumerWidget {92const GoodCounter({super.key});93@override94Widget build(BuildContext context, WidgetRef ref) {95final count = ref.watch(counterProvider);96return IconButton(97onPressed: () => ref.read(counterProvider.notifier).increment(),98icon: const Icon(Icons.add), // const on static widgets99);100}101}102```103104## Constraints105106### MUST DO107- Use `const` constructors wherever possible108- Implement proper keys for lists109- Use `Consumer`/`ConsumerWidget` for state (not `StatefulWidget`)110- Follow Material/Cupertino design guidelines111- Profile with DevTools, fix jank112- Test widgets with `flutter_test`113114### MUST NOT DO115- Build widgets inside `build()` method116- Mutate state directly (always create new instances)117- Use `setState` for app-wide state118- Skip `const` on static widgets119- Ignore platform-specific behavior120- Block UI thread with heavy computation (use `compute()`)121122## Troubleshooting Common Failures123124| Symptom | Likely Cause | Recovery |125|---------|-------------|----------|126| `flutter analyze` errors | Unresolved imports, missing `const`, type mismatches | Fix flagged lines; run `flutter pub get` if imports are missing |127| Widget test assertion failures | Widget tree mismatch or async state not settled | Use `tester.pumpAndSettle()` after state changes; verify finder selectors |128| Build fails after adding package | Incompatible dependency version | Run `flutter pub upgrade --major-versions`; check pub.dev compatibility |129| Jank / dropped frames | Expensive `build()` calls, uncached widgets, heavy main-thread work | Use `RepaintBoundary`, move heavy work to `compute()`, add `const` |130| Hot reload not reflecting changes | State held in `StateNotifier` not reset | Use hot restart (`R` in terminal) to reset full app state |131132## Output Templates133134When implementing Flutter features, provide:1351. Widget code with proper `const` usage1362. Provider/Bloc definitions1373. Route configuration if needed1384. Test file structure139140[Documentation](https://jeffallan.github.io/claude-skills/skills/frontend/flutter-expert/)141