Skip to content
Innovialabs

How to Understand an Unfamiliar Codebase Quickly

Practice4 min

In short

Do not read the code file by file: run the project, trace one user flow from the UI to the database with a debugger, back it up with tests and git history, and close the gaps with targeted questions.

The short answer

You cannot read a large project in full, and you do not need to. The method that works is to move from behaviour to code: run the system, pick one clear scenario (for example, "a user places an order") and follow it all the way through. After two or three such passes you have a skeleton that everything else attaches to.

Step 1. Run the project locally

Until the project runs, you are reading text, not a system. Getting it running already tells you a lot:

  • README, Makefile, package.json, docker-compose show which services exist and how they connect.
  • Environment variables (.env.example) reveal external dependencies: database, queue, payment gateway, file storage.
  • Startup errors are the first hints about hidden dependencies.

Write down every step that the documentation missed. That is a ready-made first contribution: an updated README is welcome in any team.

Step 2. Trace one flow end to end

Choose an action you can reproduce by hand and find its path through the layers:

  1. Entry point: a button in the UI, an API route, a bot command or a scheduled job.
  2. Handler: controller, route or handler function.
  3. Business logic: services, use cases, domain models.
  4. Data: database queries, external API calls, messages to a queue.
  5. Result: what the user gets back and what changes in the system.

A good starting trick is to search the project for a piece of UI text or the request URL. It takes you straight to the right file instead of wandering through folders.

Step 3. Use the debugger and IDE navigation

The debugger shows the real execution path, not the one you imagined.

  • Set a breakpoint in the handler and step through the flow.
  • Watch the call stack: it shows the whole chain of calls, including middleware and framework wrappers.
  • Use Go to Definition, Find Usages and Call Hierarchy instead of manual search.
  • If a debugger is not available (for example, the code only runs on a server), temporary logs with clear labels work too.

Step 4. Read the tests and git history

Tests are executable documentation. They show how the authors meant a module to be used, which edge cases matter and what counts as correct behaviour.

Git history explains why the code looks the way it does:

git log --oneline -- path/to/file      # how the file evolved
git blame path/to/file                 # who changed each line and when
git log -S "functionName" --oneline    # when a string appeared or vanished

Linked tickets and pull request descriptions often hold context that never made it into comments.

Step 5. Draw a module map

After a couple of flows, sketch a diagram: the main modules, who calls whom, where data lives, which external services are connected. Paper, a whiteboard or a plain text list is enough. The map is for you, not for a presentation: it shows where the picture is clear and where the blank spots are.

What to mark on the mapWhy
Entry points (API, UI, cron, queues)To see where requests come from
Key entities and tablesTo understand the data model
External integrationsTo know what can break from outside
Risky areas without testsTo change them carefully

Step 6. Ask targeted questions

"How does all this work?" costs a colleague an hour. "I traced checkout to OrderService.create, but I cannot see where stock is decremented — is that done by the queue?" costs five minutes and shows you have already done the groundwork.

A good question has three parts: what I am trying to understand, what I have already checked, what my hypothesis is.

Common mistakes

  • Reading folders top to bottom: context gets lost quickly.
  • Refactoring right away whatever looks odd. Odd code often has a reason that only the history reveals.
  • Staying silent for a week for fear of looking weak. Being stuck costs more than asking.
  • Not writing things down: a week later you will be figuring it out again.

FAQ

It depends on the size of the system, the quality of documentation and the complexity of the domain. Measure progress by outcome rather than time: once you can walk through the main flow yourself and ship a small change with a test, the basic onboarding is done.

We can help with this

If you'd rather get the result than figure it all out yourself — this is what we do every day.

Discuss a project

Read next

Have an idea or a task? Tell us about it

We'll reply within one business day and propose a solution. The consultation is free.