Skip to main content

write-flutter

Write, 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.

Source facts

Repository
flutter/website
Last source activity
August 25, 2026 at 17:42
Detected SKILL.md language
English
Stars
3,132
Forks
3,504

Install options

The review-first prompt is selected by default. You can switch to a direct command or download a local copy.

Review the source files

Read SKILL.md and any companion files shown by SkillsMP before deciding whether to install.

File Explorer
7 files

Showing SKILL.md

SKILL.md
Source instructions · Read-only preview
name
write-flutter
description
Write, 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.
# Write Flutter 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. Local `setState` can 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 be `const`, appear by name in DevTools and error messages, limit rebuild scope, and support independent tests. - Give widgets `const` constructors, and use `const` at creation sites wherever possible. Reusing the same widget instance lets Flutter stop the update traversal at that widget. - Keep `build` free of side effects and unnecessary work. The `build` method 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 `State` owns, and cancel subscriptions that it creates. Don't dispose objects supplied by a parent unless ownership was transferred. - After an asynchronous gap, check `mounted` in a `State` or `context.mounted` for a `BuildContext` before calling `setState`, using the context, or doing other work that requires the `State` to remain in the tree. The `use_build_context_synchronously` lint flags violations. - For `FutureBuilder` and `StreamBuilder`, obtain futures and streams before `build`, such as in `initState`, `didUpdateWidget`, or `didChangeDependencies`. Refresh them when the inputs change. Creating them inline in `build` can 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 `Column` or `Row` bounded space, usually with `Expanded`. Use `spacing` for 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 or `CupertinoTheme.of(context)` for Cupertino. Avoid duplicating visual constants at use sites. - Respect system text scaling. For intentionally constrained text, choose `maxLines` and `overflow` behavior 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 `.builder` constructors for long or unbounded lists. - Rebuild the smallest affected subtree: use `const`, extracted widgets, and the `child` parameter of `ListenableBuilder` and `AnimatedBuilder` for 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](references/widgets.md)**: Composition, constructors, keys, lifecycle, and async safety. - **[State and architecture](references/state-and-architecture.md)**: State placement, mechanism selection, separation of logic, and dependency injection. - **[Layout](references/layout.md)**: Layouts, constraint errors, overflow, unbounded height, ignored dimensions, and responsive design. - **[Design](references/design.md)**: Theming, text, and accessibility. - **[Performance](references/performance.md)**: Animations, long lists, and frame performance. - **[Testing](references/testing.md)**: Test levels, widget-test mechanics, accessibility checks, and goldens.
View on GitHub