rule

Flutter Antigravity CLI Rules: Widgets, Async UI and Platform Builds

Antigravity CLI rules for Flutter: Widgets, Async UI and Platform Builds. Append to GEMINI.md. Structure, security, and tests. Flutter 3.50, Nov 2026.

GEMINI.flutter-section.md
<!-- Append this section to GEMINI.md. Do not replace the existing file. Antigravity CLI also loads AGENTS.md, so do not paste this section into both. /context lists the loaded files. -->

Flutter Antigravity CLI Rules: Widgets, Async UI and Platform Builds

Section to append to GEMINI.md for Flutter. Antigravity CLI loads every GEMINI.md and every AGENTS.md it finds. Do not put this same section in both files. Confirm with /context.

Updated for Flutter 3.50, Nov 2026

Do not upgrade dependencies or the framework version unless the task asks.

Write for the Flutter version in pubspec.yaml and the SDK constraint. Flutter 3.50, with Dart 3.14, is the current stable release. Direct native interop is stable there, and new projects use the standalone material_ui and cupertino_ui packages. Do not bump a 3.47 app unless the task asks. Do not edit generated files under .dart_tool or plugin registries.

Project shape

Widgets are small. A screen composes widgets. State that outlives a screen lives in the project's state solution, not in a global mutable singleton you add today. Follow the existing folder split: ui, data, and domain, or whatever the repo already has.

BuildContext is only valid while the element is mounted. After await, check context.mounted before you use context for navigation, a theme, or setState.

Async UI

A future or a stream the widget owns is disposed. A StreamSubscription is canceled in dispose. Do not call setState after dispose. Show loading, empty, and error states. An error that only prints to the console looks like a frozen spinner.

Platform builds

Android and iOS configuration stay in the files the project already owns. A Kotlin migration is a named task, not a side effect of a Dart change. Read the current Gradle and Kotlin versions before you touch them. Platform channels have a typed contract. Do not pass an untyped map when the project has a pigeon or a freezed model for it.

Assets are declared. A missing asset is a test failure, not a runtime surprise you ignore.

Errors, accessibility, and tests

Catch a failed load and render the message. Do not catch (_) and continue with null data that the UI treats as empty success.

Buttons have semantics. Contrast and tap targets follow the Material or Cupertino widget you used, not a custom gesture detector with no label.

Widget tests pump the widget, find by text or key, and tap. A unit test covers a notifier or a parser without a device. An integration test is how you prove a flow. Run flutter test for the file you added. Record the output. Say when you did not run a device.

Mistakes to avoid

  • BuildContext used after await without context.mounted.
  • A subscription that is never canceled.
  • A generated plugin file edited by hand.
  • An Android build change copied from an old embedding.
  • A test that never pumps a frame and still claims the widget works.

What changed in this major

Flutter 3.50 makes direct native interop stable. New projects use standalone material_ui and cupertino_ui.

Deprecated APIs to never generate

RaisedButton was replaced by ElevatedButton.

Commands

Run flutter test for the new file.

Example

final name = await lookup();
if (!context.mounted) return;
Navigator.of(context).pop(name);

Install

Append to GEMINI.md. Keep the existing instructions.

Tools
Antigravity CLI
FlutterDartWidgets
Includes
  • GEMINI.flutter-section.md