Write Flutter
SkillWeb & browsingWrite, review, or refactor idiomatic Flutter code. Use for widgets, state and architecture, lifecycle, layout, theming, accessibility, performance, and tests. Apply alongside the write-dart skill for Dart guidance.
Available today. Use it from your connected AI after setup.
No other account needed.
Connect ahel once, and every AI you use reads what you have installed.
Then ask your AI: use the Write Flutter skill
What this skill tells your AI
The instructions your AI receives, as published by flutter/website in .agents/skills/write-flutter/SKILL.md and read by ahel’s review.
Produce Flutter code that is composable, correct across rebuilds, efficient, and accessible.
This skill builds on the write-dart skill:
apply that skill's Dart guidance,
then add the Flutter-specific guidance here.
In the references, DO and DON'T are near-absolute,
PREFER and AVOID are strong defaults,
and CONSIDER requires judgment.
Match the project
- Lints.
Follow the configuration in
analysis_options.yaml. - State management.
Identify what the project already uses
such as
setState,ChangeNotifier, provider, or Riverpod, and match its approach for shared state. LocalsetStatecan coexist with an app-level state solution. Don't add a second package or competing architecture for shared state without a concrete requirement. - Design system. Reuse the existing theme, tokens, and spacing conventions, whether the app is Material, Cupertino, or custom.
Core defaults
Apply these high-frequency Flutter rules alongside write-dart.
Composition
- Prefer small, single-purpose widget classes.
When a subtree has its own identity,
extract a named widget instead of a
_buildHeader()helper. Widget classes can beconst, appear by name in DevTools and error messages, limit rebuild scope, and support independent tests. - Give widgets
constconstructors, and useconstat creation sites wherever possible. Reusing the same widget instance lets Flutter stop the update traversal at that widget. - Keep
buildfree of side effects and unnecessary work. Thebuildmethod can run every frame. Don't perform side effects, start requests, or create futures, controllers, and other objects with identity.
State
- Default to
StatelessWidget. When something genuinely changes over time, add state. - Keep state as low in the tree as possible, moving it only to the lowest common ancestor of the widgets that need it.
- Keep significant or reusable business logic out of widgets. Widgets render state and forward events. Plain Dart classes hold the logic.
Lifecycle and async
- Dispose controllers, focus nodes, and notifiers that the
Stateowns, and cancel subscriptions that it creates. Don't dispose objects supplied by a parent unless ownership was transferred. - After an asynchronous gap,
check
mountedin aStateorcontext.mountedfor aBuildContextbefore callingsetState, using the context, or doing other work that requires theStateto remain in the tree. Theuse_build_context_synchronouslylint flags violations. - For
FutureBuilderandStreamBuilder, obtain futures and streams beforebuild, such as ininitState,didUpdateWidget, ordidChangeDependencies. Refresh them when the inputs change. Creating them inline inbuildcan restart work on every rebuild.
Layout
- Use Flutter's constraint model: constraints go down, sizes go up, the parent sets the position. Use the model to diagnose layout errors.
- Give scrollables inside a
ColumnorRowbounded space, usually withExpanded. Usespacingfor uniform main-axis gaps.
Design and accessibility
- Read shared colors and text styles from the project's theme or token system,
such as
Theme.of(context)for Material orCupertinoTheme.of(context)for Cupertino. Avoid duplicating visual constants at use sites. - Respect system text scaling.
For intentionally constrained text,
choose
maxLinesandoverflowbehavior deliberately. - Meet the target platform's minimum interactive size: 48 by 48 logical pixels for Material and Android, and 44 by 44 for iOS. Give meaningful custom interactive or visual elements semantics.
Performance
- Use
.builderconstructors for long or unbounded lists. - Rebuild the smallest affected subtree:
use
const, extracted widgets, and thechildparameter ofListenableBuilderandAnimatedBuilderfor static subtrees.
Validate
Extend the write-dart validation loop with Flutter tools.
When the environment allows it,
run the app and exercise the changed UI.
Check the console for overflow errors, exceptions,
and setState() called after dispose() warnings that analysis can't catch.
References
Read only the references relevant to the code you're writing or reviewing:
- Widgets: Composition, constructors, keys, lifecycle, and async safety.
- State and architecture: State placement, mechanism selection, separation of logic, and dependency injection.
- Layout: Layouts, constraint errors, overflow, unbounded height, ignored dimensions, and responsive design.
- Design: Theming, text, and accessibility.
- Performance: Animations, long lists, and frame performance.
- Testing: Test levels, widget-test mechanics, accessibility checks, and goldens.
Signals
- GitHub stars
- 3k
- Forks
- 3k
- Last commit
- Sep 2026
Advanced
- Catalog kind
- skill
- Gateway key
write-flutter-flutter- Source
- github.com/flutter/website