Install any skill in seconds. Free to start, no credit card required.
Get Started Free →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.
.claude/skills/jeffallan-flutter-expert/SKILL.md| Test case | Without → With | Effect | Δ tokens | Δ turns |
|---|---|---|---|---|
| case-04 | ✗→✓ | ▲ Improved | 48% | 0% |
| case-10 | ✗→✓ | ▲ Improved | 16% | 0% |
| case-18 | ✗→✓ | ▲ Improved | 45% | 0% |
| case-02 | ✓→✓ | = Same ✓ | 5% | 0% |
| case-03 | ✓→✓ | = Same ✓ | 80% | 0% |
Senior mobile engineer building high-performance cross-platform applications with Flutter 3 and Dart.
flutter pub get), configure routingflutter analyzeflutter analyze reports issues: fix all lints and warnings before proceeding; re-run until cleanflutter test after each featureflutter testflutter test --coverageflutter run --profile), eliminate jank, reduce rebuildsbuild() calls, apply const or move state closer to consumersLoad detailed guidance based on context:
| Topic | Reference | Load When | |-------|-----------|-----------| | Riverpod | references/riverpod-state.md | State management, providers, notifiers | | Bloc | references/bloc-state.md | Bloc, Cubit, event-driven state, complex business logic | | GoRouter | references/gorouter-navigation.md | Navigation, routing, deep linking | | Widgets | references/widget-patterns.md | Building UI components, const optimization | | Structure | references/project-structure.md | Setting up project, architecture | | Performance | references/performance.md | Optimization, profiling, jank fixes |
dart// provider definition final counterProvider = StateNotifierProvider<CounterNotifier, int>( (ref) => CounterNotifier(), ); class CounterNotifier extends StateNotifier<int> { CounterNotifier() : super(0); void increment() => state = state + 1; // new instance, never mutate } // consuming widget — use ConsumerWidget, not StatefulWidget class CounterView extends ConsumerWidget { const CounterView({super.key}); @override Widget build(BuildContext context, WidgetRef ref) { final count = ref.watch(counterProvider); return Text('$count'); } }
dart// ❌ WRONG: app-wide state in setState class _BadCounterState extends State<BadCounter> { int _count = 0; void _inc() => setState(() => _count++); // causes full subtree rebuild } // ✅ CORRECT: scoped Riverpod consumer class GoodCounter extends ConsumerWidget { const GoodCounter({super.key}); @override Widget build(BuildContext context, WidgetRef ref) { final count = ref.watch(counterProvider); return IconButton( onPressed: () => ref.read(counterProvider.notifier).increment(), icon: const Icon(Icons.add), // const on static widgets ); } }
const constructors wherever possibleConsumer/ConsumerWidget for state (not StatefulWidget)flutter_testbuild() methodsetState for app-wide stateconst on static widgetscompute())| Symptom | Likely Cause | Recovery | |---------|-------------|----------| | flutter analyze errors | Unresolved imports, missing const, type mismatches | Fix flagged lines; run flutter pub get if imports are missing | | Widget test assertion failures | Widget tree mismatch or async state not settled | Use tester.pumpAndSettle() after state changes; verify finder selectors | | Build fails after adding package | Incompatible dependency version | Run flutter pub upgrade --major-versions; check pub.dev compatibility | | Jank / dropped frames | Expensive build() calls, uncached widgets, heavy main-thread work | Use RepaintBoundary, move heavy work to compute(), add const | | Hot reload not reflecting changes | State held in StateNotifier not reset | Use hot restart (R in terminal) to reset full app state |
When implementing Flutter features, provide:
const usage| Case | Status | Duration (ms) | Turns | Tokens | Tool calls | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Without | With | Δ | Without | With | Δ | Without | With | Δ | Without | With | Δ | ||
case-04 | fail→pass | 13,798 | 12,787 | -7% | 1 | 1 | 0% | 2,362 | 3,486 | +48% | 0 | 0 | — |
case-01 | fail→fail | 18,796 | 20,483 | +9% | 1 | 1 | 0% | 3,777 | 4,022 | +6% | 0 | 0 | — |
case-02 | pass→pass | 17,581 | 11,995 | -32% | 1 | 1 | 0% | 3,151 | 3,318 | +5% | 0 | 0 | — |
case-03 | pass→pass | 10,017 | 10,823 | +8% | 1 | 1 | 0% | 1,840 | 3,304 | +80% | 0 | 0 | — |
case-05 | fail→fail | 16,832 | 14,052 | -17% | 1 | 1 | 0% | 2,751 | 3,635 | +32% | 0 | 0 | — |
case-06 | pass→pass | 25,834 | 13,171 | -49% | 1 | 1 | 0% | 2,572 | 3,443 | +34% | 0 | 0 | — |
case-07 | pass→pass | 12,440 | 13,804 | +11% | 1 | 1 | 0% | 2,148 | 2,783 | +30% | 0 | 0 | — |
case-08 | pass→pass | 37,672 | 26,315 | -30% | 1 | 1 | 0% | 3,911 | 4,055 | +4% | 0 | 0 | — |
case-09 | pass→pass | 9,815 | 6,123 | -38% | 1 | 1 | 0% | 1,672 | 2,169 | +30% | 0 | 0 | — |
case-10 | fail→pass | 21,186 | 16,929 | -20% | 1 | 1 | 0% | 4,219 | 4,901 | +16% | 0 | 0 | — |
case-11 | pass→pass | 9,226 | 11,448 | +24% | 1 | 1 | 0% | 1,752 | 3,472 | +98% | 0 | 0 | — |
case-12 | pass→pass | 12,714 | 7,785 | -39% | 1 | 1 | 0% | 2,453 | 2,706 | +10% | 0 | 0 | — |
case-13 | pass→pass | 9,064 | 8,503 | -6% | 1 | 1 | 0% | 1,705 | 2,583 | +51% | 0 | 0 | — |
case-14 | pass→pass | 12,747 | 12,578 | -1% | 1 | 1 | 0% | 2,650 | 4,084 | +54% | 0 | 0 | — |
case-15 | fail→fail | 7,854 | 8,284 | +5% | 1 | 1 | 0% | 1,339 | 2,512 | +88% | 0 | 0 | — |
case-16 | pass→pass | 12,026 | 9,855 | -18% | 1 | 1 | 0% | 1,848 | 2,868 | +55% | 0 | 0 | — |
case-17 | pass→pass | 18,763 | 16,026 | -15% | 1 | 1 | 0% | 3,412 | 4,421 | +30% | 0 | 0 | — |
case-18 | fail→pass | 17,824 | 17,373 | -3% | 1 | 1 | 0% | 2,769 | 4,016 | +45% | 0 | 0 | — |
case-19 | pass→pass | 12,092 | 11,410 | -6% | 1 | 1 | 0% | 2,075 | 3,480 | +68% | 0 | 0 | — |
case-20 | pass→pass | 19,066 | 13,848 | -27% | 1 | 1 | 0% | 3,878 | 3,785 | -2% | 0 | 0 | — |
case-21 | pass→pass | 15,020 | 11,752 | -22% | 1 | 1 | 0% | 2,822 | 3,389 | +20% | 0 | 0 | — |
case-22 | fail→fail | 8,070 | 5,008 | -38% | 1 | 1 | 0% | 1,368 | 2,063 | +51% | 0 | 0 | — |
DecimalAI ran this skill against gemini-3.6-flash twice over the same eval suite — once with the skill loaded and once without — and compared the two runs case by case. 22 cases were attempted. The headline lift of +14 percentage points is the difference between those two pass rates over the 22 comparable cases.
Without the skill loaded, the model failed this case. With it loaded, the same prompt on the same model passed. This is one improved case from the latest verified run; every case, including any that regressed, is in the table above.
Other measured skills in the registry, with their headline benchmark lift.