Skip to content
Back to skills

Dart Flutter Patterns

ASecurity

Use when production-ready Dart and Flutter patterns covering null safety, immutable state, async composition, widget architecture, popular state management frameworks (BLoC, Riverpod, Provider), GoRouter navigation, Dio networking, Freezed code generation,... Triggers on \"dart-flutter-patterns\", \"dart flutter patterns\", \"patterns\".

  • 2 stars
  • 0 votes
  • 0 copies
  • 1 view
  • Added September 19, 2026
ai-agentsgoreacttesting

Works with

  • cli

Security analysis

A100/100

Pro scans all 5 files and shows the line behind each finding

Scanned September 19, 2026

npx -y skills add majinmagros/magros.ai-skills --skill dart-flutter-patterns --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Dart Flutter Patterns?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Dart Flutter Patterns
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/majinmagros-dart-flutter-patterns/badge)](https://www.skillsdirectory.com/skills/majinmagros-dart-flutter-patterns)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: dart-flutter-patterns
description: "Use when production-ready Dart and Flutter patterns covering null safety, immutable state, async composition, widget architecture, popular state management frameworks (BLoC, Riverpod, Provider), GoRouter navigation, Dio networking, Freezed code generation,... Triggers on \"dart-flutter-patterns\", \"dart flutter patterns\", \"patterns\"."
metadata:
  origin: ECC
---

# Dart/Flutter Patterns

## When to Use

Use this skill when:
- Starting a new Flutter feature and need idiomatic patterns for state management, navigation, or data access
- Reviewing or writing Dart code and need guidance on null safety, sealed types, or async composition
- Setting up a new Flutter project and choosing between BLoC, Riverpod, or Provider
- Implementing secure HTTP clients, WebView integration, or local storage
- Writing tests for Flutter widgets, Cubits, or Riverpod providers
- Wiring up GoRouter with authentication guards

## How It Works

Copy-paste-ready patterns by concern (full code in `references/`):

1. **Null safety** — avoid `!`, prefer `?.`/`??`/pattern matching (`foundations.md`)
2. **Immutable state** — sealed classes, `freezed`, `copyWith` (`foundations.md`)
3. **Async composition** — concurrent `Future.wait`, safe `BuildContext` after `await` (`foundations.md`)
4. **Widget architecture** — extract to classes, `const` propagation, scoped rebuilds (`foundations.md`)
5. **State management** — BLoC/Cubit events, Riverpod notifiers + derived providers (`state-management.md`)
6. **Navigation** — GoRouter with reactive auth guards via `refreshListenable` (`navigation-networking.md`)
7. **Networking** — Dio with interceptors, token refresh with one-time retry guard (`navigation-networking.md`)
8. **Error handling** — global capture, `ErrorWidget.builder`, crashlytics (`error-testing.md`)
9. **Testing** — unit (BLoC test), widget (ProviderScope overrides), fakes over mocks (`error-testing.md`)

## Examples

```dart
// Sealed state — prevents impossible states
sealed class AsyncState<T> {}
final class Loading<T> extends AsyncState<T> {}
final class Success<T> extends AsyncState<T> { final T data; const Success(this.data); }
final class Failure<T> extends AsyncState<T> { final Object error; const Failure(this.error); }

// GoRouter with reactive auth redirect
final router = GoRouter(
  refreshListenable: GoRouterRefreshStream(authCubit.stream),
  redirect: (context, state) {
    final authed = context.read<AuthCubit>().state is AuthAuthenticated;
    if (!authed && !state.matchedLocation.startsWith('/login')) return '/login';
    return null;
  },
  routes: [...],
);

// Riverpod derived provider with safe firstWhereOrNull
@riverpod
double cartTotal(Ref ref) {
  final cart = ref.watch(cartNotifierProvider);
  final products = ref.watch(productsProvider).valueOrNull ?? [];
  return cart.fold(0.0, (total, item) {
    final product = products.firstWhereOrNull((p) => p.id == item.productId);
    return total + (product?.price ?? 0) * item.quantity;
  });
}
```

Files in this skill

  • SKILL.md3 KB
  • references/error-testing.md1.5 KB
  • references/foundations.md6.1 KB
  • references/navigation-networking.md2.3 KB
  • references/state-management.md2.3 KB

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…