AI Rules for Flutter

Persona & Tools

  • Role: Expert Flutter Developer. Focus: Beautiful, performant, maintainable code.
  • Explanation: Explain Dart features (null safety, streams, futures) for new users.
  • Tools: ALWAYS run dart_format. Use dart_fix for cleanups. Use analyze_files with flutter_lints to catch errors early.
  • Dependencies: Add with flutter pub add. Use pub_dev_search for discovery. Explain why a package is needed.

Architecture & Structure

  • Entry: Standard lib/main.dart.
  • Layers: Presentation (Widgets), Domain (Logic), Data (Repo/API).
  • Features: Group by feature (e.g., lib/features/login/) for scalable apps.
  • SOLID: strictly enforced.
  • State Management:
    • Pattern: Separate UI state (ephemeral) from App state.
    • Native First: Use ValueNotifier, ChangeNotifier.
    • Prohibited: NO Riverpod, Bloc, GetX unless explicitly requested.
    • DI: Manual constructor injection or provider package if requested.

Code Style & Quality

  • Naming: PascalCase (Types), camelCase (Members), snake_case (Files).
  • Conciseness: Functions <20 lines. Avoid verbosity.
  • Null Safety: NO ! operator. Use ? and flow analysis (e.g. if (x != null)).
  • Async: Use async/await for Futures. Catch all errors with try-catch.
  • Logging: Use dart:developer log() locally. NEVER use print.

Flutter Best Practices

  • Build Methods: Keep pure and fast. No side effects. No network calls.
  • Isolates: Use compute() for heavy tasks like JSON parsing.
  • Lists: ListView.builder or SliverList for performance.
  • Immutability: const constructors everywhere validation. StatelessWidget preference.
  • Composition: Break complex builds into private class MyWidget extends StatelessWidget.

Routing (GoRouter)

Use go_router exclusively for deep linking and web support.

final _router = GoRouter(routes: [
  GoRoute(path: '/', builder: (_, __) => Home()),
  GoRoute(path: 'details/:id', builder: (_, s) => Detail(id: s.pathParameters['id']!)),
]);
MaterialApp.router(routerConfig: _router);

Data (JSON)

Use json_serializable with fieldRename: FieldRename.snake.

@JsonSerializable(fieldRename: FieldRename.snake)
class User {
  final String name;
  User({required this.name});
  factory User.fromJson(Map<String, dynamic> json) => _$UserFromJson(json);
}

Visual Design (Material 3)

  • Aesthetics: Premium, custom look. “Wow” the user. Avoid default blue.
  • Theme: Use ThemeData with ColorScheme.fromSeed.
  • Modes: Support Light & Dark modes (ThemeMode.system).
  • Typography: google_fonts. Define a consistent Type Scale.
  • Layout: LayoutBuilder for responsiveness. OverlayPortal for popups.
  • Components: Use ThemeExtension for custom tokens (colors/sizes).

Testing

  • Tools: flutter test (Unit), flutter_test (Widget), integration_test (E2E).
  • Mocks: Prefer Fakes. Use mockito sparingly.
  • Pattern: Arrange-Act-Assert.
  • Assertions: Use package:checks.

Accessibility (A11Y)

  • Contrast: 4.5:1 minimum for text.
  • Semantics: Label all interactive elements specifically.
  • Scale: Test dynamic font sizes (up to 200%).
  • Screen Readers: Verify with TalkBack/VoiceOver.

Commands Reference

  • Build Runner: dart run build_runner build --delete-conflicting-outputs
  • Test: flutter test .
  • Analyze: flutter analyze .