Appearance
Repository Map & Codebase Context
Aider does not read your entire codebase. It reads only the files you add to the chat. But it also builds a repository map, a concise index of the most important classes, functions, and type signatures from every file in your repo. This map gives the LLM codebase-wide context without bloating the prompt. Understanding the repomap is the difference between Aider making edits that fit your architecture and Aider reinventing functions that already exist.

What you'll learn
- The repository map is a ranked index of key symbols (classes, functions, methods, type signatures) from every file in your git repo
- Aider uses a graph ranking algorithm to select only the most relevant symbols for the current chat context, fitting within a configurable token budget
--map-tokenscontrols the token budget for the repomap (default: 1024). Set to 0 to disable it completely- Only add files to the chat that need to be edited. The repomap provides context about everything else
.aiderignorefilters out parts of the repo you do not want Aider to consider, using.gitignoresyntax
The problem
If you add every file in your codebase to the chat, the LLM gets confused, costs spike, and the quality of edits drops. If you add too few files, the LLM lacks context and writes code that duplicates existing functions or ignores your project's conventions. The repomap solves both problems: you add only the files you want to edit, and Aider provides the LLM with a high-level map of everything else.
The repomap is not a file listing. It is a ranked graph of your codebase's most important symbols. Aider builds it by parsing every source file in your repo, extracting class and function definitions with their signatures, and then ranking them using a graph algorithm where files are nodes and import dependencies are edges. The most-referenced symbols surface to the top.
Options & when to use each
| Repomap setting | Command | When to use it |
|---|---|---|
| Default token budget | --map-tokens 1024 (default) | Most projects. 1024 tokens is enough for small to medium codebases |
| Increase budget | --map-tokens 4096 | Large projects where the default map misses important context |
| Decrease budget | --map-tokens 512 | Small projects or when you want to minimize token usage |
| Disable repomap | --map-tokens 0 | Trivial projects where the files you add are sufficient context. Also when using weak models that get confused by the map |
| Repo-wide map refresh | /map-refresh | You changed the codebase structure (new files, new classes) and want the map updated immediately |
| View current map | /map | You want to see exactly what Aider is sending to the LLM as context |
| Ignore parts of the repo | .aiderignore file | Monorepos, large repos, or projects with generated code you do not want indexed |
| Subtree-only mode | --subtree-only | You are working in a subdirectory of a large repo and only care about files in that subtree |
| Auto-refresh behavior | --map-refresh auto (default) | Normal usage. Aider refreshes the map when it detects file changes |
| Manual refresh only | --map-refresh manual | You have a very large repo and want to control when the expensive map rebuild happens |
| Force refresh always | --map-refresh always | You want the map rebuilt before every prompt. Slower but always current |
Build it
Step 1: See the repomap in action
Create a multi-file Python project to demonstrate the repomap:
bash
mkdir -p ~/aider-repomap && cd ~/aider-repomap && git initCreate three files that reference each other:
bash
cat > models.py << 'EOF'
from dataclasses import dataclass
from datetime import datetime
@dataclass
class User:
id: int
name: str
email: str
created_at: datetime
@dataclass
class Post:
id: int
title: str
content: str
author: User
published_at: datetime
EOF
cat > database.py << 'EOF'
from models import User, Post
from typing import List, Optional
class Database:
def __init__(self):
self.users: List[User] = []
self.posts: List[Post] = []
def add_user(self, user: User) -> None:
self.users.append(user)
def get_user(self, user_id: int) -> Optional[User]:
for user in self.users:
if user.id == user_id:
return user
return None
def add_post(self, post: Post) -> None:
self.posts.append(post)
def get_posts_by_author(self, user_id: int) -> List[Post]:
return [p for p in self.posts if p.author.id == user_id]
EOF
cat > api.py << 'EOF'
from database import Database
from models import User, Post
from datetime import datetime
db = Database()
def create_user(name: str, email: str) -> User:
user = User(id=len(db.users) + 1, name=name, email=email, created_at=datetime.now())
db.add_user(user)
return user
def create_post(title: str, content: str, author_id: int) -> Post:
author = db.get_user(author_id)
if not author:
raise ValueError(f"User {author_id} not found")
post = Post(id=len(db.posts) + 1, title=title, content=content, author=author, published_at=datetime.now())
db.add_post(post)
return post
EOF
git add . && git commit -m "Initial project structure"Now launch Aider and view the repomap:
bash
aider --model sonnet api.pyRequest the repository map from the chat interface. Aider will display the structural overview it uses to understand the broader project context.
text
> /mapAider prints the repomap. You will see something like:
text
api.py:
...
│def create_user(name: str, email: str) -> User:
...
│def create_post(title: str, content: str, author_id: int) -> Post:
...
database.py:
...
│class Database:
│ def __init__(self):
│ def add_user(self, user: User) -> None:
│ def get_user(self, user_id: int) -> Optional[User]:
│ def add_post(self, post: Post) -> None:
│ def get_posts_by_author(self, user_id: int) -> List[Post]:
...
models.py:
...
│class User:
│ id: int
│ name: str
│ email: str
│ created_at: datetime
│class Post:
│ id: int
│ title: str
│ content: str
│ author: User
│ published_at: datetimeThis is what the LLM sees as context, even though you only added api.py to the chat. It knows about Database, User, Post, and all their fields and methods without you adding those files.
Step 2: Use the repomap to write code that fits
With only api.py in the chat, ask Aider to add a new function:
text
> Add a function get_user_posts to api.py that returns all posts by a given user email addressAider knows from the repomap that:
Databasehas aget_posts_by_authormethod that takes auser_idUserhas anemailfieldDatabasehasuserslist it can iterate over
It writes code that correctly uses the existing API without you having to explain the data model:
python
def get_user_posts(email: str):
for user in db.users:
if user.email == email:
return db.get_posts_by_author(user.id)
return []This works because the repomap told the LLM exactly which functions and fields are available.
Step 3: Control the token budget
The default 1024-token budget works for most projects. Adjust it when needed:
bash
# Increase for a large codebase where edits miss context
aider --map-tokens 4096 api.py
# Decrease for a very small project
aider --map-tokens 256 api.py
# Disable completely for a single-file script
aider --map-tokens 0 script.pyYou can check how many tokens the map is using:
text
> /tokensThis shows the total token usage including the repomap, the chat history, and the files in the chat.
Step 4: Filter with .aiderignore
For large repos, monorepos, or projects with generated code, create a .aiderignore file at the repo root. It uses .gitignore syntax:
bash
cat > .aiderignore << 'EOF'
# Ignore everything by default
/*
# But include the source directory
!src/
# Exclude generated and vendored code
src/generated/
src/vendor/
node_modules/
*.min.js
EOFAider will only index and map files that pass the .aiderignore filter. This is essential for monorepos where you only work in one subproject at a time.
You can also specify a different ignore file:
bash
aider --aiderignore .aiderignore-frontendKeep multiple ignore files for different parts of a monorepo (frontend, backend, infrastructure).
Step 5: Use subtree-only for large repos
If you are deep in a subdirectory of a large repo, use --subtree-only to tell Aider to ignore everything outside your current directory:
bash
cd ~/monorepo/services/payment-api
aider --subtree-only --model sonnet main.pyAider only maps files within services/payment-api/ and below. It will not see or reference code in other services, even if they are in the same git repo.
Step 6: Refresh the map manually
When you add new files or restructure your codebase outside of Aider, the repomap may be stale. Force a refresh:
text
> /map-refreshOr set Aider to always refresh:
bash
aider --map-refresh alwaysThis rebuilds the map before every prompt. Use it when you are actively restructuring and every prompt needs the latest structure.
Step 7: Export the repomap for reference
You can export the full repomap to a file for inspection or to share with another tool:
bash
aider --show-repo-map > repo-map.mdThis dumps the map and exits. Useful for understanding what Aider sees, debugging context issues, or feeding the map into another LLM tool.
What goes wrong
| Mistake | How you notice it | The fix |
|---|---|---|
| Repomap is disabled for your model | Aider prints "Repo-map: disabled" on startup | Some weaker models get confused by the repomap. Force it on with --map-tokens 1024. But if the model produces worse results with it on, trust the default |
| LLM writes code that duplicates existing functions | The LLM implements a function that already exists elsewhere in the codebase | The repomap may not be surfacing that function. Increase --map-tokens. Or add the file containing that function to the chat as read-only with /read-only <file> |
| LLM hallucinates class methods that do not exist | Aider's edit fails or introduces a bug because it called a method that is not in the class | The repomap shows signatures but not implementations. If a class has many methods, only the most-referenced ones appear. Add the class file to the chat for full context |
| Repomap is too large and slows down prompts | Aider takes a long time to process each prompt, high token usage | Reduce --map-tokens. Create a .aiderignore file to exclude irrelevant parts of the repo. Use --subtree-only |
| Repomap shows stale symbols after a refactor | Aider references classes or functions that were renamed or deleted | Run /map-refresh to rebuild the map. Or set --map-refresh always during active refactoring sessions |
| Adding too many files defeats the purpose of the repomap | High token costs, confused LLM, worse edits | Only add files that need to be edited. Use /read-only for files you want the LLM to see but not modify. The repomap handles context for everything else |
Confirm it worked
Run this sequence. If every step succeeds, you understand how the repomap works:
bash
# 1. Check what the repomap contains for your practice project
cd ~/aider-repomap
aider --show-repo-map
# Verify you see User, Post, Database, create_user, create_post
# 2. Launch Aider with only api.py in the chat
aider --model sonnet api.py
# 3. Ask a question that requires knowledge of models.py and database.py
# The LLM should be able to answer without those files in the chat
> /ask What parameters does the User class constructor accept?
# 4. Add a new function that uses Database methods not in api.py
> Add a delete_user function to api.py that removes a user by email address
# 5. Verify the function uses existing Database API correctly
> /diffIf the LLM correctly answers questions about User and writes code that uses Database methods without you adding those files to the chat, the repomap is working.
Next: Architect Mode