Guide
Agent skills for a Flutter app: how to write them for Claude Code and Codex
AGENTS.md tells an agent the rules. A skill tells it how to do one job from start to finish, such as adding a screen or a Firestore collection. Here's how skills work, where each agent looks for them, and what we learned writing six for a Flutter codebase.
Updated
The short version
- A skill is a folder with a
SKILL.md: YAML frontmatter with anameand adescription, then Markdown instructions. - Only the name and description are loaded up front. The agent reads the body when a task matches, so a skill can be detailed without costing context on every turn.
- Claude Code reads
.claude/skills/and Codex reads.agents/skills/. Keep one folder and symlink the other. - Write skills for multi-file jobs your codebase does its own way. Point at real files, give the order of steps, and end with a check the agent can run.
AGENTS.md, CLAUDE.md and skills: which does what
| File | Loaded | Put in it |
|---|---|---|
AGENTS.md | Every session | Rules and facts: state library, navigation, generated files, commands, what "done" means |
CLAUDE.md | Every Claude Code session | One line, @AGENTS.md, plus anything only Claude Code needs |
SKILL.md | Name and description always; body when a task matches | A procedure: which files to touch, in what order, the code shape to copy, and how to verify |
If you haven't written an AGENTS.md yet, start there: AGENTS.md for Flutter has a free template. Skills build on it and shouldn't repeat its rules.
Where each agent looks
- Claude Code:
.claude/skills/<name>/SKILL.mdin the project, or~/.claude/skills/for your own skills across projects. It picks a skill when the description matches the request, and you can run one directly with/skill-name(Claude Code docs). - Codex:
.agents/skills/in the current folder and each parent up to the repo root, and~/.agents/skills/for user skills. It matches on the description too, and in the CLI you can run/skillsor type$to mention one (Codex docs). - The format is shared. Both build on the open Agent Skills specification, so a
SKILL.mdthat sticks to the standard fields works in both. Claude Code adds its own optional fields, such asdisable-model-invocation, which other agents ignore.
Claude Code's docs list .claude/skills but not .agents/skills, so to keep one copy, commit the skills under .claude/skills and add a symlink for Codex:
mkdir -p .agents
ln -s ../.claude/skills .agents/skills
git add .agents/skills Git stores the symlink as a link, but on Windows it only checks out as one with symlinks enabled (core.symlinks and Developer Mode). If your team can't use symlinks, copy the folder and add a check in CI that the two copies match.
Anatomy of a skill
This is the frontmatter of Template369's add-screen skill. As in the file, the description is a single line:
---
name: add-screen
description: Add a new screen to Template369 the way the codebase does it. Covers a main-navigation section (side menu plus phone bottom bar), a Settings sub-screen (phone push or desktop split pane), or a pushed detail screen, with a GetX controller when it needs state. Use when the user asks for a new page, screen, tab, section, settings page or feature UI.
---The rules that matter, from the specification:
name: up to 64 characters, lowercase letters, numbers and single hyphens, not starting or ending with a hyphen, and the same as the folder name.description: up to 1,024 characters, saying what the skill does and when to use it. With the name, it's all the agent sees before deciding, so put the keywords first. Claude Code also truncates long descriptions in its skill listing.- Optional fields:
license,compatibility,metadataandallowed-tools. Most skills don't need them. - Body: no fixed format. The spec suggests keeping
SKILL.mdunder 500 lines and moving long material intoreferences/, scripts intoscripts/and templates intoassets/, which the agent opens only when needed.
To check a skill against the spec, run the reference validator, skills-ref validate ./my-skill.
Our six skills run from 61 to 152 lines each. They share a pattern: context or a decision first, then the files to change, the steps, and a Verify section at the end.
The six skills in Template369
rebrand-app- Display name, bundle and application IDs on every platform, icons, in-app logos, web title and manifest, legal URLs.
connect-firebase- Point the app at your own Firebase project: FlutterFire config, web config copies, FCM service worker, VAPID key, App Check and .env.
add-screen- A main-navigation section, a Settings sub-screen or a pushed detail screen, with a GetX controller when it needs state.
add-firestore-collection- Constants keys, a model with fromMap/toMap, controller CRUD and a live stream, security rules and composite indexes.
add-subscription-plan- Stripe prices on web, App Store and Google Play products with RevenueCat entitlements on mobile, plan cards and feature gating.
add-cloud-function- A new callable: the name constant, the payload model, the controller call, UI feedback, and the contract the backend must honour.
What makes a skill work
Write the description in the user's words
People rarely ask for "add-firestore-collection". They say "store projects" or "save orders". List the phrases you expect: "Use when the user wants to store a new kind of data (projects, tasks, orders, etc.) or add fields and queries to Firestore." A vague description such as "helps with Firebase" never gets picked.
Point at real files and a real example
"Read one before writing" beats a paragraph of description. Our add-cloud-function skill opens with an "Existing pattern" section that points at the name constants, the payload models and two real controller calls, so the agent copies a working pattern instead of inventing one.
Make the first step a decision
Most Flutter jobs come in variants. A new screen can be a main section, a settings page or a pushed detail screen, and each is wired differently. A short table at the top ("pick the flavour first") stops the agent from wiring a detail screen into the side menu.
Say what the agent must not do itself
Some steps belong to a person: creating Stripe prices, App Store products, Firebase projects. Our add-subscription-plan skill has a "Manual steps" section headed "the human does these in dashboards; never automate them", and the agent lists them for a person to do.
End with a check it can run
Every skill ends with a Verify block of commands. All six run flutter analyze, and each adds what fits its job: dart format on the touched files, flutter test, a grep proving a new name is defined exactly once, a web build, or a hand check such as resizing the window below 850 px and above 1,250 px. Without a check, "looks done" is the only signal.
Don't repeat AGENTS.md
Rules that apply everywhere, such as "GetX only" or "never edit firebase_options.dart", live in AGENTS.md. If a skill restates them, the two drift apart. A skill should only add what's specific to its job.
A starter skill you can copy
Here's the outline for a Flutter "add a screen" skill. Replace the <…> parts with your app's real files and conventions. It's free to copy and adapt.
---
name: add-screen
description: Add a new screen to <App> the way this codebase does it,
including routing, state and tests. Use when the user asks for a new page,
screen, tab, section or feature UI.
---
# Add a screen
## Pick the kind first
| Kind | Use for | Wiring |
|---|---|---|
| Top-level section | A main area such as "Projects" | <where tabs or menu items are listed> |
| Detail screen | Drill-down from a list, a form | <how you push, e.g. context.push('/projects/:id')> |
## Files
- New: lib/features/<feature>/<feature>_screen.dart
- New if it has state: <where your controllers, notifiers or blocs live>
- Edit: <router file>, <menu or tab list>
## Copy this pattern
Read <path to an existing screen> first and match its structure:
<a short skeleton of a screen in your app>
## Steps
1. Add the route in <router file>.
2. Create the screen from the skeleton.
3. Add the menu or tab entry, if it's a top-level section.
4. Add a widget test in test/<feature>/.
## Don't
- Don't add a second state or routing library.
- Don't edit generated files; regenerate them.
## Verify
- dart format --output=none --set-exit-if-changed <touched files>
- flutter analyze: no new issues (state the count before and after)
- flutter test
- Check the screen at phone width and at desktop width, in light and dark mode.Testing a skill
- Ask for the job in plain words, as a user would: "add a Projects page". Check that the agent loads the skill without being told. If it doesn't, the description is missing the words people use.
- Run it directly to test the body on its own:
/add-screenin Claude Code, or$add-screenin Codex. - Read the diff against the skill. Every file it touched should be in the Files list, and the Verify output should be in its summary.
- Fix the skill, not the output. When the agent gets something wrong, change the line that misled it, so the next run is right too.
Common mistakes
- One giant skill. "Everything about our app" never matches a request well. Write one skill per job.
- Describing the app you plan. A skill that names files that don't exist yet sends the agent hunting. Write it from the code as it is.
- No variants. A single path for a job that comes in three shapes produces the wrong wiring two times out of three.
- Asking the agent to do dashboard work. Creating store products, Stripe prices or Firebase projects needs a person signed in. List those steps for the human, and never put API keys in a skill.
- Two copies. Separate files under
.claude/skillsand.agents/skillsgo out of sync. Use the symlink.
Common questions
What if my agent doesn't load skills?
A skill is plain Markdown, so any agent can follow one if you point at the file: "Follow .claude/skills/add-screen/SKILL.md to add a Projects page."
How many skills should a Flutter app have?
Start with the two or three jobs you repeat most and that touch several files: new screens, new data types, and anything involving payments or the backend. Add more when you notice yourself explaining the same job twice.
Should skills include code?
Short skeletons, yes, copied from the real codebase so they compile. For anything long, point at the existing file instead, so the skill doesn't go stale when the code changes.
How we checked
Format rules come from the Agent Skills specification, the Claude Code behaviour from its skills docs, and the Codex paths and invocation from its skills docs, all read on 30 October 2026. The Template369 examples are quoted from the six skills in the template repo.