Guide

AGENTS.md for Flutter: a free template and how to fill it in

AGENTS.md is the file AI coding agents read before they touch your repo. Here's a template written for Flutter apps, what each section is for, and the mistakes that make agents ignore it.

Updated

Download the template (AGENTS.md)

The short version

  • Put one AGENTS.md at the repo root. Codex, Cursor, GitHub Copilot's coding agent, Gemini CLI and many other agents read it. Claude Code reads it too.
  • Write what an agent can't guess: your state library, how routes are added, which files are generated, the commands, and what "done" means.
  • Keep it short and true. An agent follows the file over its own guesses, so a wrong line does more harm than a missing one.

What AGENTS.md is

AGENTS.md is "a simple, open format for guiding coding agents": a Markdown file with the build steps, test commands and conventions that would clutter a README. The Agentic AI Foundation, under the Linux Foundation, now looks after the format. In a monorepo you can add one per package; agents read the nearest file, and a direct instruction in chat overrides any file.

Claude Code reads AGENTS.md directly from v2.1.277 when the repo has no CLAUDE.md. If you have a CLAUDE.md, add a line with @AGENTS.md to it, and Claude Code loads both. That works on every version (Claude Code docs). Watch for one catch: any CLAUDE.md, .claude/CLAUDE.md or CLAUDE.local.md in your folder or above it, even a personal, gitignored one, stops Claude Code reading AGENTS.md directly. The import line is the reliable setup.

Why Flutter needs its own

Generic AGENTS.md examples miss the things that trip agents up in Flutter projects:

  • Several state libraries look equally valid. Without a rule, an agent adds Riverpod to a Bloc app, or Provider to a GetX one. Name yours and say "don't add a second".
  • Generated files. firebase_options.dart, build_runner output (*.g.dart, *.freezed.dart, *.gr.dart, *.mocks.dart), gen-l10n output and the plugin registrants are rewritten by tools. List them so the agent regenerates them instead of editing them.
  • The analyzer baseline. Many apps start with existing flutter analyze issues. Record the count, and ask for before-and-after numbers, so new issues stand out.
  • Secrets in the bundle. Everything in lib/ and in bundled assets, including a bundled .env, ships to users. Say so, or an agent will put an API secret there.
  • Phone and desktop. If the app is responsive, give the breakpoints and require a check at both ends.

The template

Replace every <…> placeholder and delete sections that don't apply. It's free to copy and change for your own projects.

<!--
  AGENTS.md template for a Flutter app.
  Replace every <…> placeholder and delete sections that don't apply.
  Or let your agent do it: "Read this repo and fill in AGENTS.md. Only write what you can confirm from the code."
  Keep it short and true. An agent follows what's written here over what it guesses, so a wrong line costs more
  than a missing one.
-->

# AGENTS.md: <App name>

Guide for AI coding agents (Claude Code, Codex, Cursor and others) working in this repo.
<If you also keep a `CLAUDE.md`, put `@AGENTS.md` in it so Claude Code reads these same rules. Otherwise delete this line.>

<One or two sentences: what the app does, who uses it, and which platforms ship (iOS, Android, web, macOS, …).>

## Project map

| Path | What lives there |
|---|---|
| `lib/main.dart` | <Bootstrap order, e.g. `Firebase.initializeApp` → DI setup → `runApp(App)`> |
| `lib/<state folder>/` | <Where state lives: blocs, providers, controllers, notifiers> |
| `lib/<data folder>/` | <Repositories, API clients, models with `fromJson`/`toJson`> |
| `lib/<ui folder>/` | <Screens and widgets, and how they're grouped (by feature or by type)> |
| `lib/<routing file>` | <Router config> |
| `test/` | <What the tests cover and what they need (fakes, emulators, nothing)> |

**Not in this repo:** <backend, security rules, infrastructure, design files. Say where they live, or "none".>

## Architecture rules

**State: <Riverpod | Bloc | Provider | GetX | Signals | setState only>.** Don't add a second state library.
- <How a new feature's state is created and disposed.>
- <Where side effects (network, storage, analytics) are allowed to run.>

**Navigation: <go_router | auto_route | Navigator 2 | named routes | other>.**
- <How to add a route, and the file(s) that must change together.>

**Data.**
- <Where field and collection names come from (constants, generated code). Never inline string keys if that's the rule.>
- <Serialization: hand-written `fromJson`/`toJson`, `json_serializable`, `freezed`.>
- <Timestamps, IDs, null handling conventions.>

**UI.**
- Colors come from `Theme.of(context).colorScheme` and text styles from `Theme.of(context).textTheme`. Don't hard-code colors.
- <Breakpoints for phone / tablet / desktop, if the app is responsive.>
- <Localization: `gen-l10n` with ARB files in `lib/l10n/`, or "none: strings are hard-coded English".>

## Commands

Run from the repo root. Tested with Flutter <version> (Dart <version>).

```bash
flutter pub get
dart run build_runner build --delete-conflicting-outputs   # <only if the repo uses code generation>
flutter analyze                                           # compare issue counts before and after
dart format lib test
flutter test
flutter run -d <chrome | macos | device id>
```

<Anything the app needs before it runs: an `.env` copied from `.env.example`, `flutterfire configure`, emulators.>

## Generated and machine-owned files: don't hand-edit

- <`lib/firebase_options.dart` (FlutterFire CLI)>
- <`*.g.dart`, `*.freezed.dart`, `*.gr.dart`, `*.mocks.dart` (build_runner: json_serializable, freezed, auto_route, mockito)>
- <`app_localizations*.dart` (gen-l10n, from the ARB files)>
- <`GeneratedPluginRegistrant.*` under android/, ios/ and macos/, `ios/Flutter/Generated.xcconfig`, `.flutter-plugins-dependencies`, and `linux/flutter/generated_*`, `windows/flutter/generated_*` (rewritten by `flutter pub get` and builds)>

## Never do

- Never commit secrets: `.env`, service-account JSON, keystores (`*.jks`, `key.properties`), App Store Connect keys (`*.p8`), API secret keys.
- Never put a server-side secret in the Flutter app. Everything in `lib/` and in bundled assets ships to users.
- Never deploy, publish or change remote state without explicit approval: <`firebase deploy`, store uploads, `git push`, …>. Prepare the change and tell the human what to run.
- Never hand-edit the generated files listed above.
- Don't bump major dependency versions or restructure folders unless the task asks for it.
- <Project-specific rules: keys you must never rename, files owned by another team, …>

## Definition of done

1. Every touched `.dart` file passes `dart format --output=none --set-exit-if-changed`.
2. `flutter analyze` reports no new issues compared with before the change. Say both counts.
3. `flutter test` passes. New logic that doesn't need a device or backend has a unit test.
4. New UI works at phone and desktop widths, in light and dark mode.
5. The summary lists the files changed and every manual step left for the human (consoles, deploys, store settings).

## Known issues (as of <date>; update this list when fixed)

- <Baseline: `flutter analyze` reports <n> issues on Flutter <version>.>
- <Anything rough that an agent should work around rather than "fix" unasked.>

How to fill it in

  1. Let the agent draft it, then check every line. Ask it to read the repo and fill in only what it can confirm from the code. Delete anything it guessed.
  2. Run every command in the Commands block on a fresh clone. If one fails, fix the line or the setup step before it.
  3. Record the analyzer count under Known issues, with the Flutter version.
  4. Add your "never do" rules: keys that must never be renamed, folders owned by another team, commands that deploy.
  5. Keep it current. When you fix a known issue or change a convention, change the file in the same commit.

Common mistakes

  • Describing the app you plan, not the one you have. An agent follows the file, so it builds toward a structure that doesn't exist yet.
  • Pasting the README. Install instructions for humans and marketing copy waste the agent's context. Keep AGENTS.md to rules and facts.
  • Too long. Claude Code's docs suggest staying under about 200 lines for its instruction files, because longer files are followed less reliably. The same applies here.
  • Rules with no reason. "Don't use Navigator.push" gets worked around. "Use go_router so deep links work on web" gets followed.
  • Two files that disagree. If you keep a CLAUDE.md, import AGENTS.md from it rather than copying, so the rules can't drift apart.

A filled-in example

Template369, our Flutter SaaS boilerplate, ships a complete AGENTS.md built from this structure, with six step-by-step skills for common tasks such as adding a screen or a Firestore collection. See Build with an AI agent for what's in it.

How we checked

Facts about the format come from agents.md, and the Claude Code behaviour from its memory docs, both read on 19 October 2026. Agent support changes quickly, so check the current list on agents.md.