ClaudeCode

How to write a good CLAUDE.md for Expo and FastAPI

Most of the silly mistakes an agent makes in a project come from the same place: it doesn’t know how you work. It runs the wrong command, creates files in the wrong folder, or rewrites something you had done a certain way for a good reason.

Developer working with an AI agent on a code project

CLAUDE.md is the file where you tell it. Claude Code reads it at the start of every session and keeps it in mind for the whole conversation, so anything you put there is something you don’t have to repeat. It also works the other way around: if you fill it with noise, the agent gets lost just like it would without the file.

Where it goes

The main one lives in the project root and is committed to the repository, so the whole team shares it. You can also have a personal one in ~/.claude/CLAUDE.md with your preferences for every project, and files inside subfolders that get loaded when the agent works on that part of the code. To get started, /init generates one from the project. Treat it as a draft, not as the final result, because it tends to come out long and generic.

What to put in it

The rule that works for me: write what I would tell someone who joins the project today and can’t ask me anything.

  • The exact commands to run, test, build and check the code.
  • The folder structure in a few lines, and where each kind of thing goes.
  • The conventions you can’t see by reading the code, like how files are named or how errors are handled.
  • What it should never touch: generated folders, migrations already applied, sensitive config files.
  • Odd decisions with their reason. A single line like “don’t upgrade X, it breaks Y” stops the agent from fixing something that is that way on purpose.

What to leave out

Anything the agent can already see for itself. There’s no need to explain that it’s a React project or to list the dependencies from package.json. Don’t copy library documentation either, and don’t paste style rules your linter already enforces. And never put keys, tokens or passwords in there, because the file goes to the repository.

There is a less obvious limit too: length. The more you add, the less weight each line has. If an instruction really matters, keep it short and clear instead of buried three screens down.

Example for an Expo project

This is roughly what I would write for a mobile app. Change the commands for the ones you use.

Mobile app with Expo and React Native, TypeScript.

Commands
- Start: npx expo start
- Type check: npx tsc --noEmit
- Lint: npx expo lint
- Tests: npm test

Structure
- app/ screens and routes (Expo Router)
- components/ reusable UI, one component per file
- services/ API calls, nothing in the screens
- hooks/ shared logic

Rules
- Never edit the android/ and ios/ folders, they are generated with prebuild.
- All server calls go through services/api.ts.
- New dependencies are installed with npx expo install, not npm install.
- Texts are always in the translation files, never hardcoded.

Example for a FastAPI project

REST API with FastAPI, Python 3.12, PostgreSQL.

Commands
- Run: uvicorn app.main:app --reload
- Tests: pytest
- Lint: ruff check .
- Apply migrations: alembic upgrade head

Structure
- app/routers/ endpoints, only validation and calling the service
- app/services/ business logic
- app/models/ SQLAlchemy models
- app/schemas/ Pydantic schemas

Rules
- Never edit a migration that is already applied, create a new one.
- Business logic goes in services, not in the routers.
- Every new endpoint needs at least one test.
- Secrets come from environment variables, never from the code.

When the project grows

If you have frontend and backend in the same repository, put a short CLAUDE.md in the root with what they share and one in each folder with what is specific. The one in mobile/ talks about Expo and the one in api/ talks about FastAPI. The agent loads the one from the folder it is working in, so you don’t explain migrations while it is touching a screen.

You can also import other files with @, for example @docs/architecture.md, so you don’t duplicate text you have already written.

Keep it alive

Treat it like code. When the agent does something you didn’t want, don’t just fix it: add the rule that would have prevented it. And every so often, delete what no longer applies. A CLAUDE.md that only grows ends up contradicting itself.

A quick test: ask Claude Code to do a small task in a fresh session and see if it gets the commands and folders right without you saying anything. If it fails at something, you know which line is missing.

Leave a Comment