FastCode: The Repo Indexer That Skims a Codebase Before It Reads It

HKUDS's open-source system turns repositories into layered structure, then retrieves just enough context to answer a question without flooding the model.

12 min read • View on GitHub • More from HKUDS

A cartographer studies a layered city map spread across a desk, lifting one transparent sheet to reveal a single route while the larger map stays folded beneath it. The scene explains FastCode's core idea: read the structure first, then zoom into only the smallest useful slice of a repository.
FastCode treats a codebase like a map with layers, not a pile of files.
Key Takeaways

Most code assistants still do the blunt thing. They load a pile of files, hope the model notices the right lines, and pay for all the noise. FastCode starts with the opposite assumption: the best answer comes from reading less, but reading in the right order.

FastCode builds a map before it answers

The pipeline starts with structure, not embeddings alone, then deepens context only when the first pass is uncertain.

The important move lives in the parser and indexer. FastCode breaks code into `CodeElement` objects, so the system can search at the file, class, or function level instead of treating every file as one opaque blob. That is why it can skim signatures, docstrings, and relationships first, then descend into bodies only when the question still looks unresolved.

retrieval:
  semantic_weight: 0.5
  keyword_weight: 0.5
  graph_weight: 1

The config makes the strategy explicit. Semantic search and keyword search share the load, while graph information gets its own weight, which is a quiet admission that code is not just text. The answer you want is often in the call graph, the parent class, or the neighboring function, not in the nearest paragraph.

Why the retrieval loop matters

The iterative agent in `iterative_agent.py` is the other half of the design. Instead of assuming the first search is enough, it watches confidence, caps the number of rounds, and only widens the search when the initial slice feels thin. That is how FastCode avoids turning every question into a full repository scan.

ApproachFirst moveToken pressureFailure mode
Brute-force context stuffingRead whole files firstHighFinds the answer, but burns tokens on irrelevant code
Generic chunked RAGSplit by length and embed the chunksMediumMatches similar text, but loses structure and relationships
FastCodeSkim AST structure firstLow until neededExpands only when confidence says the first slice is not enough

That comparison is the whole product thesis. FastCode is not trying to win by being more chatty than other tools. It is trying to make the model earn its context.

The repo also wants to leave the IDE

The presence of `mcp_server.py`, `api.py`, `web_app.py`, and the `nanobot/` directory matters because it broadens the target. FastCode is not only a local helper for Cursor or Claude Code. It is trying to become a knowledge layer that other clients can ask, from an editor, a web app, or a team chat bridge.

OpenCode is the community's response - an open source, terminal-based coding agent that works with any model you want.

Yuval Avidani, Author, YUV.AI Blog · YUV.AI on OpenCode

I built cocoindex-code- a super lightweight embedded MCP that: Only re-indexes changed files - built on a Rust-based incremental indexing engine. Lets your coding agent search by meaning, not just text matching. Creates semantic embeddings of those chunks. Parses your code into ASTs using tree-sitter, extracting meaningful chunks (functions, classes, methods). The result? 70% token savings and noticeably faster coding agent responses.

Unknown, Author, Indie Hackers Post · Indie Hackers on cocoindex

The surrounding ecosystem is converging on the same problem from different angles. One camp optimizes model freedom, another trims token waste, and FastCode sits in the middle by making repository structure itself the interface.

What to open first in the code

  1. `fastcode/main.py` shows how loading, parsing, indexing, caching, and querying fit into one orchestration loop.
  2. `fastcode/indexer.py` and `fastcode/parser.py` reveal how the repo becomes file, class, and function level structure.
  3. `fastcode/iterative_agent.py` shows where confidence checks decide whether the system should search wider.
  4. `mcp_server.py` shows how the same retrieval engine escapes the editor and becomes a tool for other clients.

If you only read one file, make it `fastcode/main.py`. It shows the project in miniature, because everything important is there: load, index, retrieve, judge, repeat. Read `iterative_agent.py` next, because that is where FastCode decides whether a question deserves more context or less.