Skip to content

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.

Gnome mascot

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-tokens controls 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
  • .aiderignore filters out parts of the repo you do not want Aider to consider, using .gitignore syntax

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 settingCommandWhen 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 4096Large projects where the default map misses important context
Decrease budget--map-tokens 512Small projects or when you want to minimize token usage
Disable repomap--map-tokens 0Trivial 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-refreshYou changed the codebase structure (new files, new classes) and want the map updated immediately
View current map/mapYou want to see exactly what Aider is sending to the LLM as context
Ignore parts of the repo.aiderignore fileMonorepos, large repos, or projects with generated code you do not want indexed
Subtree-only mode--subtree-onlyYou 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 manualYou have a very large repo and want to control when the expensive map rebuild happens
Force refresh always--map-refresh alwaysYou 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 init

Create 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.py

Request the repository map from the chat interface. Aider will display the structural overview it uses to understand the broader project context.

text
> /map

Aider 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: datetime

This 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 address

Aider knows from the repomap that:

  • Database has a get_posts_by_author method that takes a user_id
  • User has an email field
  • Database has users list 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.py

You can check how many tokens the map is using:

text
> /tokens

This 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
EOF

Aider 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-frontend

Keep 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.py

Aider 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-refresh

Or set Aider to always refresh:

bash
aider --map-refresh always

This 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.md

This 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

MistakeHow you notice itThe fix
Repomap is disabled for your modelAider prints "Repo-map: disabled" on startupSome 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 functionsThe LLM implements a function that already exists elsewhere in the codebaseThe 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 existAider's edit fails or introduces a bug because it called a method that is not in the classThe 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 promptsAider takes a long time to process each prompt, high token usageReduce --map-tokens. Create a .aiderignore file to exclude irrelevant parts of the repo. Use --subtree-only
Repomap shows stale symbols after a refactorAider references classes or functions that were renamed or deletedRun /map-refresh to rebuild the map. Or set --map-refresh always during active refactoring sessions
Adding too many files defeats the purpose of the repomapHigh token costs, confused LLM, worse editsOnly 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
> /diff

If 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