← Back to the catalog

Skill · Version 1.0.0

Flutter project conventions

Applies Flutter’s asynchronous, navigation and widget-lifecycle rules within the state-management patterns the project already uses.

flutter-conventions

See how it helps

When is it useful?

Use it when a Flutter feature rebuilds excessively, leaks controllers or updates a screen after it has disappeared.

What does it help you do?

  • Preserves the project’s established state-management approach.
  • Handles navigation, lifecycle and controller disposal explicitly.
  • Checks mounted contexts after awaits and isolates expensive computation.

Try asking this

Fix a Flutter form that navigates after its screen has been closed. Start a delayed save and leave the screen before it completes. No disposed context should navigate or show a message, and controllers must be released.

Detailed documentation

Read the skill’s original instructions, examples and checks in their authored language.

Details…Show less

Flutter & Dart

Build maintainable, 60/120fps Flutter applications with layered architecture, fine-grained widget rebuilds, sound null safety and idiomatic Dart.

1. Layered architecture and state management

  • Follow the repository's single state-management pattern (Riverpod, Bloc/Cubit, Provider or ChangeNotifier + ViewModel)—never introduce a second competing state library.
  • Separate UI and business logic:
    • UI layer (Screens & Widgets): renders immutable state, handles layout/animations, and dispatches user intents. Keep build() pure, synchronous and free of side effects or network calls.
    • Logic layer (Notifiers / Blocs / ViewModels): coordinates screen state (AsyncValue / sealed state classes), form validation and optimistic updates.
    • Data layer (Repositories & Services): encapsulates HTTP clients (dio / http), local databases (drift / sqflite), secure storage (flutter_secure_storage) and platform channels.
  • Narrow rebuild scope:
    • Extract reusable StatelessWidget / ConsumerWidget classes rather than helper methods returning Widget so Flutter's element tree short-circuits rebuilds.
    • Use const constructors everywhere possible and subscribe narrowly (ref.watch(provider.select((s) => s.field)), BlocSelector, context.select).

2. Navigation, predictive back and lifecycle

  • Declarative routing (go_router / Navigator 2.0):
    • Pass compact path/query parameters (state.pathParameters['id']) rather than non-serializable extra objects so routes survive deep links and state restoration.
    • Centralize auth redirects using GoRouter(redirect: ..., refreshListenable: authRepository) and use context.go() when replacing the navigation stack (post-login, post-checkout) vs context.push() for drill-down screens.
  • Android 14+ predictive back & pop interception:
    • Use PopScope<T>(canPop: !hasUnsavedChanges, onPopInvokedWithResult: (didPop, result) async { if (didPop) return; ... }) instead of the deprecated WillPopScope or onPopInvoked.
  • Lifecycle & controller cleanup:
    • Use AppLifecycleListener (or WidgetsBindingObserver) to pause cameras/timers/streams on onPause / onInactive and refresh on onResume.
    • Always dispose TextEditingController, FocusNode, ScrollController, AnimationController and StreamSubscription in dispose().

3. Async safety, Isolates and code generation

  • Async context safety: never create a Future or Stream inside build(). After any await in a widget or stateful callback, check if (!context.mounted) return; before calling Navigator, ScaffoldMessenger or Theme.of(context).
  • Offload heavy CPU work to Isolates: run heavy JSON parsing, encryption or image processing via await Isolate.run(() => ...) or compute(). When calling platform plugins from a background isolate, initialize the messenger first with BackgroundIsolateBinaryMessenger.ensureInitialized(rootIsolateToken).
  • Codegen & models: model domain data and union states with Dart 3 sealed class / pattern matching or @freezed + @JsonSerializable. Never hand-edit .g.dart or .freezed.dart files—run dart run build_runner build --delete-conflicting-outputs.

4. Scrolling, adaptive layout and platform channels

  • Use ListView.builder, ListView.separated or CustomScrollView with SliverList.builder for dynamic lists; set itemExtent or prototypeItem when item heights are uniform.
  • Build responsive layouts with LayoutBuilder, MediaQuery.sizeOf(context) and SafeArea (avoiding MediaQuery.of(context) when only size or padding is needed, so keyboard animations do not rebuild unrelated subtrees).
  • Prefer type-safe Pigeon (@HostApi(), @FlutterApi()) or well-structured MethodChannel wrappers that catch PlatformException and MissingPluginException.

5. Verification

  • Run flutter analyze, dart format --output=none --set-exit-if-changed, unit tests and widget tests (testWidgets, pumpWidget, pumpAndSettle).

Before you finish

  • Widgets use const constructors, narrow selectors and proper dispose() cleanup.
  • context.mounted checked after every await; no Future/Stream created in build().
  • PopScope (onPopInvokedWithResult) and go_router auth/deep-link rules respected.
  • Codegen updated, flutter analyze clean, and flutter test passes.

Included files 2

  • LICENSE.txt
  • SKILL.md

About this skill package

flutter-conventions

flutter-conventions: Build mobile apps that handle navigation, native integrations, offline data and interrupted sessions reliably.

Details…Show less

flutter-conventions

flutter-conventions: Build mobile apps that handle navigation, native integrations, offline data and interrupted sessions reliably.

Includes the complete skill and its supporting files (2 files). The exact authored scope is preserved below.

Original skill description (source language)

Use when working on a Flutter or Dart app, widgets (StatelessWidget, StatefulWidget, Slivers), state management (Riverpod, Bloc/Cubit, Provider), go_router, AppLifecycleListener, PopScope, Isolates, platform channels/Pigeon, freezed/build_runner or flutter test.

Install the skill, review its source and trust settings, then enable it for the relevant project or agent.

Requirements

  • Orqestria installed on your computer.