Cursor Agent is the terminal coding agent from Cursor, started with cursor-agent in the root of your Flutter project. It reads project instructions from AGENTS.md or .cursor/rules and can plan, edit, run tests, and explain changes. For Flutter developers, this means you can keep your IDE for layout and hot reload, while the agent handles structured changes to widgets, state, tests, and platform channels. See Cursor Agent for the agent itself.
A terminal pair programmer for Flutter
Flutter work involves more than writing Dart: you have widget trees, state management with Provider, Riverpod, or Bloc, build_runner generated code, and platform channels for Android and iOS. Cursor Agent suits this because it can run the same terminal commands you already use — flutter pub get, flutter analyze, flutter test — and apply edits across multiple files. It can generate the repetitive parts of Flutter development, such as Riverpod providers, Freezed data classes, method channel boilerplate, and widget test scaffolding. The agent is most useful when you treat it as a pair programmer that follows explicit conventions instead of guessing your project structure. For example, it can read pubspec.yaml to see dependencies, then generate a Riverpod provider that matches your existing folder pattern. It can also produce widget tests that use pumpWidget and tester.tap patterns already present in your test suite, so the generated tests look native to the project.
Configuring AGENTS.md for predictable Flutter edits
Before the first real task, give the agent a short AGENTS.md or .cursor/rules file that contains the commands, folder conventions, and Flutter-specific guardrails for your project. This is not a prompt file for a single task; it is the default context for every task. The file should be short, under about 60 lines, because large AGENTS.md files dilute the instructions. If your project has platform-specific code, include a rule that Android changes go under android/ and iOS changes under ios/, and that the agent should not edit those directories unless explicitly asked. If you use Bloc instead of Riverpod, replace the state management rule with your Bloc conventions, including event and state class naming. A realistic AGENTS.md for a Flutter project might look like this:
# AGENTS.md
## Commands
- Install dependencies: flutter pub get
- Run app: flutter run
- Run all tests: flutter test
- Run a single test: flutter test test/path/to/file_test.dart
- Analyze: flutter analyze
- Generate code: dart run build_runner build --delete-conflicting-outputs
## Folder conventions
- lib/features/<feature>/presentation: widgets and screens
- lib/features/<feature>/application: Riverpod providers and notifiers
- lib/features/<feature>/domain: models and repository interfaces
- lib/features/<feature>/data: repository implementations and data sources
- lib/core/platform: method channels and platform wrappers
## Rules
- Use Riverpod for state management unless the task says otherwise.
- Keep widgets const where possible; extract reusable widgets instead of long build methods.
- Never edit generated files under lib/gen/ by hand. Run build_runner instead.
- For every new widget or state change, add or update a widget test under test/.
- Run `flutter analyze` before considering a task complete.
- Keep platform-channel calls behind a service class so tests can mock them.
If you prefer .cursor/rules, split the same content into one rule file for commands and one for Flutter conventions. The key is that the agent sees the commands and structure every time it starts, so it does not ask which state management library you use or where tests live.
A practical edit-test-review loop
Treat each task as a small, reviewable step. Start by asking the agent to read the relevant files and propose a plan before editing. Then let it edit one file or one logical unit at a time, run the narrowest relevant test, run flutter analyze, and show the diff. Review the diff yourself, especially for widget tree changes and platform-channel code, before moving on. Example prompts for common Flutter tasks:
- Refactor the
LoginScreenfrom a StatefulWidget to a ConsumerWidget using Riverpod. First list the existing state and callbacks, then change one file at a time and runflutter test test/login_screen_test.dartafter each edit. - Add a method channel to read the device locale on Android and iOS. Create a
LocaleServiceinlib/core/platform/, update the settings page to use it, and add a widget test with a mocked method channel. - Write widget tests for the product list covering loading, empty, and error states. Use the existing mock repository in
test/mocks/mock_product_repository.dartand runflutter test test/product_list_test.dart. - Convert
CartScreento use aCartNotifierwith Riverpod. Keep the public widget API unchanged, run the existing cart tests, and update any failing tests only if the expected behavior changed. - Run
flutter analyze, fix all warnings inlib/features/audio/, and keep the changes minimal. Then runflutter test test/audio_player_test.dartto verify dispose behavior.
When you review the diff, check that widget keys are not removed accidentally, const constructors were not dropped in a large refactor, and state updates happen before any BuildContext is used across an asynchronous gap. If a change touches a platform channel, open the Android and iOS files even if the Dart code compiles. For a broader safety pattern around agent edits, see How to vibe code safely: a practical workflow.
Flutter strengths and watchpoints
Cursor Agent is reliable for mechanical Flutter work when the rules are clear. This table shows where it is strong and where you should review more carefully:
| Task area | Agent strength | Watch closely |
|---|---|---|
| Widget refactors | Extracts widgets, applies const, renames callbacks and parameters | Layout overflows, missing keys, state loss after rebuild, stale BuildContext across async gaps |
| State management | Generates Riverpod providers, Bloc events, notifiers, selectors | Provider scope mistakes, missing dispose, unnecessary rebuilds, state not updating due to == or copyWith issues |
| Platform channels | Writes MethodChannel/EventChannel boilerplate and service wrappers | Type mismatches between Dart and Kotlin/Swift, missing setMockMethodCallHandler in tests, UI thread issues |
| Widget tests | Creates tests for loading, empty, error, and interaction states | Overly broad tests, missing semantics, false positives from pumpAndSettle timeouts |
| Code generation | Runs dart run build_runner build for Freezed, json_serializable, and Riverpod | Conflicts with existing generated files, version pinning, forgetting to import part files |
The main pitfalls specific to Flutter are layout overflows that appear only at runtime, hot reload hiding state problems until a full restart, platform-channel code that compiles but fails on one OS, and widget tests that pass while the visual layout is broken. For example, a refactor that extracts a ListView can introduce an RenderFlex overflow that only shows in a narrow test viewport. A state change can miss a copyWith field and appear fine until a hot restart. The agent may write a widget test that never actually pumps the changed widget because the file is imported but not exercised. Always run the app or a golden test for visual changes.
Verifying Flutter changes with analyze and tests
Make verification non-negotiable in every task. After the agent edits code, ask it to run flutter analyze first, then the smallest test file related to the change, then the full flutter test suite before you merge. For state management changes, include tests that pump the widget and interact with the provider, not just unit tests for the notifier. For platform-channel work, use TestDefaultBinaryMessengerBinding.instance.defaultBinaryMessenger.setMockMethodCallHandler in tests and verify that the agent added both the mock and a call to tearDown. If the agent cannot run an Android emulator or iOS simulator, ask it to run flutter test --platform chrome or flutter test integration_test/app_test.dart only when a device is available, and note that it should not claim a platform-specific fix is complete without at least one OS-level test. For visual changes, generate and update golden files with flutter test --update-goldens, then review the PNG diff. Ask the agent to run flutter test with --coverage and report which files have less than 70% coverage if you use coverage gates, but treat coverage as a signal, not a target. For golden tests, keep the golden files in version control and review any diff that changes more than expected.
Running several agents on Flutter worktrees with AgentVera
AgentVera can run Cursor Agent and other terminal coding agents side by side in one window, each in its own real terminal panel. For a Flutter team working on multiple features at once, the most valuable pieces are parallel git worktrees so agents don’t overwrite each other’s lib/ files, automatic code review that flags widget and state mistakes with file:line links, checkpoints to roll back a bad refactor, and an approval queue for platform-channel changes that touch both Dart and native code. It is a practical way to combine several agents without losing control over a Flutter codebase; see Best tools to run AI coding agents in parallel (2026).
Final notes
Cursor Agent works well in a Flutter project when you give it a precise AGENTS.md, break tasks into small steps, and always verify with flutter analyze, flutter test, and a careful diff review. Use it for widget refactors, state management changes, platform-channel plumbing, and test generation, but keep visual and layout changes under human review. With multiple agents, AgentVera adds separation and review so several Flutter tasks can move forward in parallel without stepping on each other.