Flutter
Flutter's own docs (docs.flutter.dev, every page also served as markdown at <page-url>.md) and the Flutter team's agent skills (flutter/agent-plugins) set the guidance this skill follows. Most outcomes in a Flutter app come down to a few mechanisms: widgets stay free of data logic while a repository owns each piece of data, page-backed routes are the ones that deep-link, and tests and profiling only mean something when frames are pumped and builds are measured in profile mode. Third-party material is marked where it appears: parts of VERSIONS.md (the full history matrix, deprecation table and upgrade runbook) come from the [RandalSchwartz] changelog skill; RIVERPOD.md is ApparenceKit's Riverpod practice; APP-EVENTS.md holds ApparenceKit's global service events dispatcher; TESTING-RECIPES.md is ApparenceKit's widget-test recipes; and sections tagged [ApparenceKit] or [FlutterPro] in the other files (project rules for agents, Drift, server reachability, writing and testing a plugin, Slang) are community practice. Each marks where it differs from the official sources. Screen layout, themes, typography, reusable widgets and visual animation are in flutter-ui SKILL.md. Community UX and app-polish tips with a design-review mode are flutter-ux SKILL.md; custom RenderObjects (layout, painting, hit testing, semantics) are flutter-render-objects SKILL.md. The Dart language, packages and Dart-only tests are dart SKILL.md; store submission is app-store-connect SKILL.md and google-play SKILL.md; Patrol and Maestro end-to-end tests are e2e-testing SKILL.md; in-app subscriptions are revenuecat SKILL.md; crash and error reporting is sentry SKILL.md.
Apply only the routes and checks for the selected job. Read a linked skill's named file from its installed folder when available, or from the linked source. Report an unavailable required reference instead of inventing it. [skill-authoring, DISTRIBUTION.md#composing-skills]
| The job | Read |
|---|---|
Layers (views, view models, repositories, services, optional use cases), recommendations by priority, project structure, DI with provider, commands, the Result type, optimistic state, state management options, the Compass case study |
ARCHITECTURE.md |
Navigator or Router, go_router setup, parameters, shell routes and tabs, redirects and auth, errors, type-safe routes, Android App Links, iOS Universal Links, third-party link plugins |
ROUTING-AND-DEEP-LINKS.md |
http requests, showing them with FutureBuilder, JSON by hand, parsing off the main isolate, generated models and code generation, local storage, key-value, SQL and Drift, offline first and sync, server reachability |
DATA-AND-NETWORKING.md |
| Platform channels, codec types, Android and iOS hosts, threading, Pigeon, and the native files a Flutter app edits | PLATFORM-INTEGRATION.md |
| Writing a plugin: package versus plugin, templates, native implementations, federation, FFI choices and four testing layers | PLUGINS.md |
| Unit tests, mocks and fakes, widget tests and choosing a pump, golden tests, integration tests and running them, performance integration tests, debugging tests | TESTING.md |
| Community widget-test recipes (isolates with runAsync, ValueVariant, screen sizes, finders, expected errors, go_router) | TESTING-RECIPES.md |
Frame budget, build cost, const, saveLayer, opacity and clips, lazy lists, isolates, build modes, profiling, DevTools, Impeller, app size |
PERFORMANCE.md |
| The third-party ApparenceKit Riverpod architecture: code-generated async notifiers, AsyncValue UI, Ref extensions, app events, a paginated list, toasts, and where it disagrees with the provider-based guidance | RIVERPOD.md |
| App-wide service events: ApparenceKit's global dispatcher, stream lifecycle and buffering alternatives | APP-EVENTS.md |
Accessibility regulations and release checklist, contrast and tap targets, Semantics, screen readers, web semantics, guideline tests and scanners |
ACCESSIBILITY.md |
flutter_localizations and gen-l10n, delegates, ARB files, placeholders, plurals and select, number and date formats, locale resolution, l10n.yaml options, Slang as an alternative |
LOCALIZATION.md |
Flavors, --dart-define, version numbers, Android and iOS release builds, signing, app bundles, obfuscation, SwiftPM and CocoaPods, AGP 9 and built-in Kotlin, UIScene, continuous delivery with a handoff to App Store Connect fastlane lanes, a minimum-version gate, secrets |
BUILD-AND-RELEASE.md |
Widget previews (annotations, IDE/CLI launch, web limits), the official agent plugin, installing it per client, the Dart and Flutter MCP server and its tools, connecting to a running app, the hot reload rule, project rules for agents (CLAUDE.md, Cursor rules, commands, MCP servers), docs for agents, AI features inside apps |
AGENT-TOOLING.md |
Current stable and release history, what 3.47 and 3.44 changed, minimum OS and toolchain, breaking changes, material_ui and cupertino_ui, deprecations, Material 3, upgrading an old app |
VERSIONS.md |
| Screen layouts, responsive sizing, themes, typography, reusable widgets and visual animation | flutter-ui SKILL.md |
| Community UX tips (forms, sheets, scrolling, interaction feedback, notifications, device features, lifecycle, web, formatting) and a design review of an app | flutter-ux SKILL.md |
Writing a custom RenderObject: layout, child models, painting, compositing, hit testing and mouse cursors, semantics, diagnostics |
flutter-render-objects SKILL.md |
The rules
- Never mix UI rendering with business logic or data fetching. Views hold only show/hide conditions, animation, layout from device information and simple routing; view models get repositories through their constructors and keep them private; the repository is the single source of truth and the only class that changes its data.
- For screen layout and visual UI, read flutter-ui SKILL.md; the responsive layout rule and its checks live there.
- Be lazy with lists: for unknown or large item counts always use
ListView.builderorGridView.builder, prefer many smallconstwidgets, and keepbuild()cheap. - Fail loudly on the network: throw (or return an error
Result) on any unexpected status code and never returnnullon failure, castjsonDecoderesults to typed models, and move parsing that takes longer than 16 ms off the main isolate withcompute(). - Use
go_routerfor navigation, "the preferred way to write 90% of Flutter applications": page-backed routes deep-link, named routes andNavigator.pushpages do not, andcontext.go()beats imperativepushfor browser history. - Pump after every interaction in a widget test: a tap calls
setState()but the test environment does not rebuild on its own, so callpump()(orpumpAndSettle()for animations) before the nextexpect(). - Measure performance in profile mode on a physical device, the slowest one your users might reasonably use; debug builds and emulators are not indicative of release performance.
- Keep secrets out of the app and its repository: storing secrets in an app is a poor security practice (obfuscation only renames symbols), and
key.propertiesand the upload keystore never go into source control.
Prove it
flutter analyze is clean and flutter test passes (through the MCP run_tests tool when an agent runs it); no view imports a repository or service; a request that returns 404 or 500 ends in an error state, not an endless spinner; deep links open the target screen from a cold start on both platforms; performance claims come from a profile build on a device; git ls-files shows no keystore or key.properties; and every file's own Prove it checks pass for the parts you touched.