A context file is good when an AI assistant who's never seen the repo can write a correct, idiomatic patch on the first try. It's bad when it slows the model down with noise or, worse, contradicts the actual code. Optimize for "first-try patch quality" and most other questions answer themselves.
There's no canonical structure for CLAUDE.md or AGENTS.md files yet, and the patterns I see in the wild are all over the place. Some are 10,000-line essays nobody reads; some are three bullets that don't help. Here's what I've landed on for React Native projects after writing these for half a dozen production apps.
Two layers, not one
A single root file is rarely enough on a mobile codebase. The best setup I've found is two layers:
- A root
CLAUDE.mdorAGENTS.mdwith stack, conventions, and the things AI assistants reliably get wrong. - Per-directory
AGENTS.mdfiles in any folder with non-obvious patterns —app/(auth)/,app/(tabs)/,lib/auth/,lib/payments/,convex/orsupabase/.
The root file is what the model loads at the start of every session. The directory files are what it picks up when it's editing files in that area. Neither replaces the other.
What goes in the root file
Keep it under 300 lines. If it's longer, you're using it as a wiki, and the model's attention will spread thin.
# Project name
One-line description.
## Stack
- Expo SDK 55, React Native 0.81
- TypeScript strict mode
- expo-router for navigation
- Supabase for auth and data
- RevenueCat for payments
- Sentry for errors
- Zustand for client state, TanStack Query for server state
## Directory layout
- app/ — screens (file-based routing)
- components/ — shared UI
- lib/ — non-UI code; one folder per concern (auth, payments, db)
- assets/ — images, fonts, lottie
## Things to never do here
- Don't import AsyncStorage from "react-native" — it's removed
- Don't add react-navigation; we use expo-router exclusively
- Don't render the Apple Sign In button on Android
- Don't bypass the entitlement check in lib/payments/access.ts
## Run commands
- Dev: yarn start
- iOS: yarn ios
- Android: yarn android
- Type check: yarn tsc
- EAS build: eas build --profile preview --platform ios
## Where to look for context
- Auth flow lives in lib/auth/ — read its AGENTS.md before editing
- Paywall flow lives in lib/payments/ — read its AGENTS.md before editing
- Server functions live in convex/ — see convex/AGENTS.md
That's roughly the whole thing. No essays. No mission statement. No "we value clean code." The model doesn't need motivation; it needs rules.
What goes in a per-directory file
A per-directory AGENTS.md is for the patterns that only matter when you're actually inside that folder. The auth folder's file might be:
# AGENTS.md — lib/auth
## Contract
- Always check `useUser()` for auth state, never read SecureStore directly
- Token refresh is handled in supabase.ts — don't add another path
- New auth methods must update both `signIn` and `signOut` paths consistently
## File responsibilities
- supabase.ts — client and session lifecycle
- session.ts — useUser hook + provider
- providers/apple.ts — Apple Sign In flow (returns identity token)
- providers/google.ts — Google flow (returns id_token)
- providers/email.ts — email magic link
## Common mistakes
- Don't store tokens in AsyncStorage. Use SecureStore.
- Don't await `useUser()` — it's a hook.
- Don't write a useEffect that signs the user out on focus loss.
Each section is a directive. No introductions. No prose.
What to leave out
The file gets weaker the longer it is. Things to cut ruthlessly:
- History. Why a decision was made matters to a human reviewer; the model just needs the current rule. "We tried X, then moved to Y" is wasted context.
- General coding wisdom. "Use meaningful variable names." The model already does this. Reserve the file for project-specific rules.
- Anything you don't enforce. If
CLAUDE.mdsays "we have 100% test coverage" and the codebase has 12 tests, the model trusts the code. The contradiction makes every rule weaker. - Big code samples. Keep examples to a few lines that establish the pattern. If you need a long example, point to the actual file: "see
lib/auth/session.tsfor the canonical hook." - Architecture diagrams. They render as plain text in most agent tools and add tokens without adding signal.
How big is too big
Heuristics I use:
- Root file: 100 to 300 lines. Below 100, you're missing rules. Above 300, you're padding.
- Per-directory file: 30 to 100 lines. They should be skimmable.
- Total context across files: under ~3,000 tokens for the working set the model loads at session start. That's roughly all your context files combined.
If you're well past these numbers, the file is doing two jobs: rulebook for the model and documentation for humans. Split them. The human-facing docs go in a docs/ or vibe/ folder. The model-facing rules stay tight.
The "things AI assistants get wrong here" section
This is the highest-leverage section in the entire setup, and it's the one most people forget. Every time the model writes a wrong pattern in your codebase, you add a line:
- "Don't call signInAsync inside useEffect — only on user press."
- "Don't add a navigation library — we use expo-router."
- "Don't generate config plugins; ours live in plugins/ and are versioned."
- "Don't add ESLint rules without checking package.json — we already have a strict config."
After a few weeks, this section becomes the project-specific equivalent of a senior engineer's gut check. The model writes patches that look like they came from someone who's actually worked here.
Updating the file is the work
The setup is not "write CLAUDE.md once and forget it." The setup is: every wrong pattern that the model produces becomes a line in the file. Otherwise it'll happen again next session.
I treat this the way I treat fixing a flaky test: when it bites, fix it durably. Five minutes of edits to the context file save days across a project.
Templates worth stealing from
- Shipnative's
AGENTS.mdfiles — across the boilerplate, landing page, and docs, set up exactly the way I'd recommend for a multi-app monorepo. expo/exporepo's contribution docs — good ground truth for current Expo conventions.- Anthropic's Claude Code docs on memory and skills — the official guidance on how Claude Code reads
CLAUDE.mdand per-directory rules.
If you want a working multi-file setup to copy, Shipnative is the version I keep up to date for exactly this workflow. If you'd rather build it yourself, the structures above are the bones — what makes them useful is the rules you add over time, not the scaffolding.
For more on the pattern across a monorepo, see Layered Context Docs for Vibecoding Monorepos and Cursor Rules for React Native.
