BoilerplateHub

Flutter App AGENTS.md Template

For a Flutter application targeting iOS and Android with Riverpod for state, go_router for navigation, and build_runner for generated code. It assumes a feature first directory structure and freezed models. Use it when generated files and platform config are the main things an agent should leave alone.

FlutterDartRiverpodgo_routerfreezed
AGENTS.md
Download
# AGENTS.md

This is a Flutter application for iOS and Android using Riverpod, go_router, and code generation.

## Project

Stack: Flutter stable channel, Dart 3, Riverpod (code generated providers), go_router, freezed, json_serializable, dio.

Layout:

- `lib/main.dart` entry point and provider scope
- `lib/app/router.dart` go_router configuration, the single source of routes
- `lib/app/theme.dart` ThemeData, colors, typography
- `lib/features/<feature>/presentation/` screens and widgets
- `lib/features/<feature>/application/` providers and controllers
- `lib/features/<feature>/domain/` freezed models and value objects
- `lib/features/<feature>/data/` repositories and API clients
- `lib/shared/` widgets and utilities used by more than one feature
- `test/` mirrors `lib/`

Generated files end in `.freezed.dart`, `.g.dart`. They are outputs, not sources.

## Commands

```bash
flutter pub get                                    # install dependencies
flutter run                                        # run on the connected device
flutter run -d ios / -d android                    # target a platform
dart run build_runner build --delete-conflicting-outputs   # codegen, run after model or provider changes
dart run build_runner watch --delete-conflicting-outputs   # codegen in watch mode
flutter analyze                                    # static analysis, must be clean
dart format lib test
flutter test                                       # unit and widget tests
flutter test test/features/auth                    # one directory
flutter build apk --release
flutter build ipa --release
flutter clean                                      # when the build cache is suspect
```

After changing any freezed model, JSON model, or annotated provider, run build_runner before running or testing. A missing codegen step shows up as unresolved symbols.

## Platform notes

- Permissions: declare in `android/app/src/main/AndroidManifest.xml` and `ios/Runner/Info.plist`. Both are required, and iOS needs a human readable usage string.
- Minimum versions: iOS 13, Android minSdk 23. Do not raise them without approval.
- Android system back is handled by go_router. Use `PopScope` for any screen that must confirm before leaving.
- Use `Theme.of(context).platform` for behavioral differences, not `Platform.isIOS`, so widget tests stay controllable.
- Safe areas: wrap scaffold bodies in `SafeArea`. Do not hardcode notch or status bar heights.
- Adding or upgrading a plugin with native code requires `flutter clean` and a full rebuild, hot reload will not pick it up.
- Test on both a physical Android device and an iOS simulator before calling a UI change done.

## Code style

- Widgets are classes, never functions returning a Widget. Extract a `StatelessWidget` instead of a `_buildX` method.
- Use `const` constructors wherever possible. `flutter analyze` must pass with zero warnings.
- State lives in providers. A `StatefulWidget` is only for animation controllers, focus nodes, and text controllers.
- Watch providers with `ref.watch` in build and `ref.read` in callbacks. Never call `ref.read` during build.
- Models are freezed classes with `fromJson`. No hand written `copyWith` or `==`.
- Repositories return domain models, never raw `Map<String, dynamic>`.
- Navigation goes through named routes in `lib/app/router.dart`. No `Navigator.push` with an inline `MaterialPageRoute`.
- Colors, spacing, and text styles come from the theme. No raw `Color(0xFF...)` in a widget.
- Async work in the UI layer goes through `AsyncValue` and renders loading and error states explicitly.

## Boundaries

Do not touch without explicit instruction:

- Any `.freezed.dart` or `.g.dart` file. Change the source and rerun build_runner.
- `ios/` and `android/` build configuration, signing, Gradle files, and `Podfile.lock`.
- `pubspec.lock`. Change `pubspec.yaml` and run `flutter pub get`.
- App identifiers, version, and build number in `pubspec.yaml`.
- `.github/workflows/`, fastlane configuration, and store metadata.

Needs human review: new plugins with native dependencies, permission additions, deep link configuration, and any change to `lib/app/router.dart` route names.

## Testing

- `flutter test` runs unit and widget tests.
- Required unit tests: repositories, controllers and notifiers, and any pure Dart helper.
- Widget tests cover screens with conditional rendering, using `ProviderScope` overrides for fakes.
- Integration tests in `integration_test/` cover sign in and the primary user flow only, they are slow and stay minimal.
- Golden tests are used only for shared design system widgets. Regenerate deliberately, never with a blanket update.
- A bug fix ships with a test that fails before the fix.

## Git workflow

- Branch from `main`: `feat/short-description`, `fix/short-description`.
- Conventional commits: `feat(profile): add avatar upload`.
- Generated files are committed, but regenerate them in a separate commit from behavior changes so the diff stays readable.
- PR description includes screenshots from both platforms for any UI change.
- Never commit to `main`.

What each section does

Project

Flutter projects split between a feature first and a layer first structure, and an agent will pick the wrong one without guidance. Naming the directories and the generated file suffixes prevents new code landing in the wrong place. It also flags which files are outputs rather than sources.

Commands

Codegen is the step an agent forgets, and the resulting errors look like unrelated type failures. Listing build_runner alongside analyze, format, and test makes the loop complete. Build commands for each platform belong here so verification is possible.

Platform notes

iOS and Android differ in permissions, back navigation, and minimum SDK, and those files live outside the Dart tree entirely. Recording the known differences keeps an agent from editing native config blindly. It also documents when a full rebuild is unavoidable.

Code style

Dart has a strong analyzer, so the rules worth writing are the ones it cannot enforce: widget composition, const usage, and where state lives. Riverpod in particular has conventions that determine whether the app rebuilds efficiently. These are all checkable in review.

Boundaries

Generated files, pubspec.lock, and the ios and android directories break the build when hand edited, and the damage is not obvious in a diff. Signing and store configuration should stay with a human. Say which files are regenerated rather than written.

Testing

Flutter distinguishes unit, widget, and integration tests, and each has a different cost, so the file should say which is expected where. Naming the required layers keeps effort on logic rather than pixel assertions. Golden tests need an explicit policy or they drift.

Git workflow

Generated files inflate diffs and cause spurious conflicts, so the commit policy for them needs stating. Screenshots from both platforms give a reviewer something to check. The rest follows normal branch and commit conventions.

Which agents read this file?

Claude Code looks for CLAUDE.md. Most other agents and editors read AGENTS.md. Rather than maintaining both and letting them drift, keep one real file and symlink the other:

ln -s AGENTS.md CLAUDE.md
git add AGENTS.md CLAUDE.md

Git stores the symlink, so it survives cloning on macOS and Linux. On Windows it needs developer mode or a stub file that references the real one. The full comparison is in CLAUDE.md vs AGENTS.md.

Other templates

Reviews

Leave a comment

Your rating (optional)

0/2000