How Forward Deployed Engineers Read a Codebase They Have Never Seen
The Situation Every FDE Knows
It is 9am. You are onsite at a customer. Their lead engineer gives you access to a private GitHub repo โ 200,000 lines of code, four years of commits, zero documentation. You have a standup in two hours where you are expected to have an opinion on why their integration is failing.
This is not an edge case for a forward deployed engineer. This is Tuesday.
The ability to read an unfamiliar codebase fast โ not just understand it eventually, but get productive in hours โ is the core technical skill that separates effective FDEs from engineers who need two weeks of onboarding before they can contribute anything. Nobody at the customer site has two weeks to spend onboarding you. You are there because they need help now.
This post covers the exact process experienced FDEs use to orient themselves in an unknown codebase fast.
๐ฏ Quick Answer (30-Second Read)
- Start with the entry points, not the files โ find main, index, app โ wherever execution begins
- Read the dependency manifest first โ package.json, requirements.txt, go.mod tells you the entire tech stack in 30 seconds
- Follow the data, not the code โ trace one real request from entry to database and back
- Use git log before reading files โ recent commits tell you what is actively changing and who owns what
- Ask one question, not ten โ find the one engineer who knows the most and ask them where the bodies are buried
Why Most Engineers Read Codebases Wrong
The instinct when dropped into an unfamiliar codebase is to start reading files. You open the repo, pick a file that looks important, and start reading top to bottom. An hour later you understand that one file reasonably well and have no idea how it connects to anything else.
This is the wrong approach. Reading files in isolation gives you local knowledge with no map. You understand the trees but have no sense of the forest.
The right approach is top-down orientation before bottom-up reading. Understand the shape of the system first. Understand how the pieces connect. Then read individual files with context about what they are supposed to do.
Step 1 โ Read the Dependency Manifest (5 Minutes)
Before opening a single source file, open the dependency manifest.
- Node.js:
package.json - Python:
requirements.txtorpyproject.toml - Go:
go.mod - Ruby:
Gemfile - Java:
pom.xmlorbuild.gradle
This file tells you the entire tech stack in under five minutes. What web framework are they using. What ORM. What authentication library. What queue system. What testing framework.
# Quick scan on any project
cat package.json | grep -A 50 "dependencies"From the dependency list you know immediately whether you are in a Django monolith or a FastAPI microservice, whether they use Prisma or raw SQL, whether they have a job queue or not. This context changes how you read every file that follows.
What to Look For
Framework choice tells you the architectural pattern. Express means a hand-rolled API structure you need to discover. NestJS means a rigid module system you can navigate by convention. Django means MVC with a specific file layout you already know.
Unusual or niche packages are flags. An unfamiliar package in the dependency list is often where the interesting custom logic lives. If you see a package you do not recognise, look it up before reading the source โ it might be doing something the rest of the code depends on heavily.
Version numbers tell you how old the codebase is and whether it is actively maintained. A package.json full of dependencies three major versions behind is a codebase that has not been seriously updated in years.
Step 2 โ Read the Directory Structure (5 Minutes)
Do not open files. Read the directory tree.
find . -type f -name "*.ts" | head -50
# or
tree -L 3 -I node_modulesThe directory structure tells you how the original engineers thought about the system. A src/services/ folder means they separated business logic. A src/controllers/ folder means MVC. A flat src/ with fifty files means nobody thought too hard about organisation.
Look for:
- Where do routes or API endpoints live
- Where does database access happen
- Is there a clear separation between business logic and infrastructure
- Are there multiple apps or packages in one repo (monorepo)
- Is there a
scripts/orjobs/directory suggesting async processing
You are building a mental map. Not reading yet โ mapping.
Step 3 โ Find the Entry Point (10 Minutes)
Every application has one place where execution begins. Find it.
- Node.js:
mainfield in package.json, orsrc/index.ts,src/app.ts,server.ts - Python:
main.py,app.py,wsgi.py, or whereveruvicornorgunicornpoints - Go:
main.goin the root orcmd/directory
Read the entry point file completely. It is usually short. It tells you what middleware the application uses, how the server is configured, what the startup sequence is, and where routes are registered.
// A typical Express entry point tells you everything
const app = express();
app.use(cors());
app.use(authMiddleware); // โ auth is applied globally
app.use('/api/v1', apiRoutes); // โ all routes are under /api/v1
app.use(errorHandler); // โ there is a centralised error handler
app.listen(PORT);Five lines of entry point code and you know the middleware chain, the route prefix, and that there is a centralised error handler. That is significant context.
Step 4 โ Read Git Log Before Reading Code (10 Minutes)
git log --oneline -50
git log --oneline --all --since="3 months ago"Recent git history is the most underused tool for codebase orientation. It tells you:
- What has been actively changed recently
- Which files are touched most often (high churn = high importance or high instability)
- What the team has been working on
- Whether there are patterns in commit messages that reveal architecture decisions
# Find the most frequently changed files
git log --pretty=format: --name-only | sort | uniq -c | sort -rg | head -20The files that change most often are the files that matter most. They are the core of the application. Start your reading there.
Commit messages also tell you what problems the team has been fighting. Fifteen commits in a row fixing the same authentication module means authentication is where the complexity lives. Seven commits touching a payment integration means the payment integration is fragile. This knowledge changes where you look when something is broken.
Step 5 โ Trace One Real Request End to End (30 Minutes)
Pick one API endpoint or user action that is relevant to why you are there. Trace it from the moment a request arrives to the moment a response is returned, touching every layer.
For a typical REST API this means:
HTTP Request arrives
โ
Router matches the path โ which file, which function
โ
Middleware runs โ auth check, validation, logging
โ
Controller/Handler โ what business logic runs
โ
Service layer โ what the core logic actually does
โ
Database query โ what data is fetched or written
โ
Response constructed โ what gets returned
Do not try to understand every function deeply on the first pass. Read the function signatures and return types. Understand what each layer receives and what it returns. You are tracing the shape of the flow, not memorising the implementation.
This single trace gives you more working knowledge of the system than reading fifty individual files. You now understand one path through the entire application, which gives you an anchor for understanding everything else.
Step 6 โ Find Where the Complexity Actually Lives (15 Minutes)
Every codebase has one or two places where the real complexity is concentrated. The rest is plumbing. Your job is to find the complexity fast.
Signals that complexity is nearby:
- Files longer than 500 lines
- Functions with more than five parameters
- Heavy use of try/catch with specific error types
- Comments that say "do not touch this" or "this is complicated because"
- TODO comments that have been there for years
- A file named
utils.tsorhelpers.pythat is 800 lines long
# Find the longest files
find src -name "*.ts" -exec wc -l {} \; | sort -rn | head -20
# Find TODO comments that reveal known problems
grep -r "TODO\|FIXME\|HACK\|XXX" src/ --include="*.ts"The TODO comments are particularly valuable for an FDE. They are the engineering team's honest notes about what is broken or incomplete. Reading them gives you a picture of the system's known weak points before you discover them the hard way.
Step 7 โ Ask the One Question That Unlocks Everything
After your independent orientation, find the engineer who has been on the project longest and ask one specific question:
"If I were going to break something important without meaning to, where would it be?"
This question gets you the information that no amount of code reading reveals โ the implicit knowledge, the undocumented constraints, the integration that works but nobody knows why. Every senior engineer on a long-running project has this knowledge. Most of them will never volunteer it unless you ask directly.
Do not ask "can you walk me through the codebase." That wastes their time and yours. Ask the specific question that surfaces the most dangerous knowledge first.
My Take
The reason most engineers struggle with unfamiliar codebases is that they treat reading code like reading a book โ start at the beginning and work forward. Codebases are not books. They are systems, and systems are understood by tracing flows, not reading files. The best FDEs I have seen in action do something that looks almost lazy at first โ they spend the first hour not reading code at all. They read manifests, read git logs, read directory trees, run the application and poke at it. They build a map before they navigate. The worst outcome in a customer codebase is confident wrongness โ understanding one part deeply and making assumptions about the rest that turn out to be incorrect. That is how you introduce a bug in a system you were sent to fix. The best outcome is productive uncertainty โ knowing exactly what you understand, knowing exactly what you do not, and knowing precisely where to look for the answer to any specific question. Right now the tooling for codebase orientation is getting genuinely good โ Claude Code, Cursor, and Copilot Chat can all give you a reasonable architectural summary of a repo in minutes. But the mental model for how to read a codebase fast is still a human skill. AI tools accelerate the process; they do not replace the judgment about where to look first. Where this is heading: FDEs who combine systematic orientation habits with AI-assisted code reading will operate at a level that was not possible two years ago โ getting productive in a new codebase in under an hour rather than under a day.
The Orientation Checklist
Use this on every new customer codebase:
โก Read dependency manifest โ identify full tech stack
โก Read directory structure โ build mental map without opening files
โก Find and read the entry point completely
โก Run git log โ find high-churn files and recent focus areas
โก Trace one real request end to end
โก Find the longest and most complex files
โก Read all TODO/FIXME comments
โก Ask one engineer: "where would I accidentally break something?"
โก Run the application locally if possible โ use it before reading it
Real FDE Use Case
An FDE was sent to a fintech customer to diagnose why their transaction reconciliation was producing incorrect totals intermittently. The codebase was a Python Django application, four years old, no documentation.
First 10 minutes: read requirements.txt โ identified Celery for async tasks, which immediately flagged that reconciliation was probably running as a background job, not a synchronous process. Read git log โ found 23 commits in the last two months all touching tasks/reconciliation.py. That file was the answer before reading a single line of business logic.
Traced the reconciliation task end to end: found a race condition where two Celery workers were occasionally processing the same batch of transactions simultaneously. The fix was a database-level lock that took 20 lines of code.
Total time from repo access to root cause: 90 minutes. Not because the engineer was exceptional โ because the orientation process pointed directly at the right file before any deep reading happened.
Frequently Asked Questions
How long should it take to get productive in an unfamiliar codebase?
For a well-structured codebase with reasonable separation of concerns, an experienced FDE should be able to make a meaningful contribution within half a day. "Meaningful contribution" means identifying a real issue, proposing a fix, or implementing a scoped change โ not rewriting the system. Poorly documented legacy codebases take longer, but the orientation process is the same โ it just surfaces more surprises.
Should I run the application before reading the code?
Yes โ if you can. Running the application and using it as a user gives you context that code reading cannot. You see the actual behaviour, which tells you what the code is supposed to do before you read what it actually does. This gap between intended and actual behaviour is often exactly where the bug lives.
What if there is no documentation at all?
Most production codebases have minimal documentation. Treat the tests as documentation โ they describe what the code is supposed to do and often reveal edge cases the author was thinking about. If there are no tests either, the git commit messages and the entry point are your only map. Start there and move slowly.
How do FDEs handle codebases in languages they do not know well?
The orientation process is language-agnostic. Dependency manifests, directory structures, git logs, and entry points exist in every language. An FDE who does not know Go can still read go.mod, understand the directory structure, trace a request through the router, and find the high-churn files. Deep language knowledge matters for implementation โ it matters less for orientation.
What tools do experienced FDEs use for codebase exploration?
Beyond the standard IDE, the most useful tools are: git log and git blame for history, grep or ripgrep for finding patterns across files, Claude Code or Cursor for summarising unfamiliar modules, and the application itself running locally. The goal is always the same โ build the map before you navigate.
Conclusion
Reading an unfamiliar codebase fast is a learnable, repeatable skill. It is not about being smart or having seen the technology before. It is about following a systematic orientation process that builds a map of the system before you start reading individual files.
Read the manifest. Read the directory tree. Find the entry point. Read the git log. Trace one request. Find the complexity. Ask the one question that surfaces implicit knowledge.
Do this consistently and you will be productive in any customer codebase in hours, not days. That speed is what makes an FDE valuable โ and what makes the role impossible to replace with someone who needs two weeks to get up to speed.
Related reads: What Is a Forward Deployed Engineer ยท How AI Coding Agents Write and Debug Code Autonomously ยท How to Structure a Codebase for AI Agents