█
LastWrite
  • > Curriculum
  • > Pricing
  • > For Educators
  • > About
  • > Contact
Log InGet Started

Questions, concerns, bug reports, or suggestions? We read every message, write to us at [email protected].

More ways to reach us →
LastWrite

Structured computer science lessons for aspiring developers and security professionals.

[email protected]

(201) 785-7951

Mon–Fri, 9 AM–5 PM EST

Learn

  • Curriculum
  • Pricing

Company

  • About
  • For Educators & Schools
  • Contact Us

Legal

  • Terms of Service
  • Privacy Policy
© 2026 LastWrite. All rights reserved.
Curriculum/Software Engineering/Engineering Fundamentals/Reading Unfamiliar Code and Project Structure
40 minBeginner

Reading Unfamiliar Code and Project Structure

After this lesson, you will be able to: Navigate an unfamiliar codebase with a repeatable strategy, recognize how real projects are structured (monorepo vs multi-repo, layers, modules, services), and orient yourself fast on day one of a new job.

On your first day at any job, you inherit a codebase someone else wrote. Nobody hands you a tour. Reading unfamiliar code quickly is the skill that separates engineers who are productive in week one from engineers who flail for a month. It is a learnable, repeatable process, and most schools never teach it.

Prerequisites:Software Engineering vs Programming

Reading code is most of the job

Studies of working engineers put time spent reading code at roughly ten times time spent writing it. Every feature you add, every bug you fix, every review you do starts with understanding code you did not write. The instinct of a beginner is to read a file top to bottom like a book. That does not work for a 200-file project. You need a strategy that starts from a question and follows the code that answers it.

How real projects are laid out

Two big shapes. A monorepo keeps many projects (web app, API, shared libraries) in one Git repository, usually under a top-level `packages/` or `apps/` folder. A multi-repo (polyrepo) splits each project into its own repository. Inside any one project you will usually find: `src/` for source, `tests/` or `__tests__/` for tests, a config layer (`package.json`, `tsconfig.json`, `.env.example`), and often a layered structure: routes or controllers at the edge, services or domain logic in the middle, and data access at the bottom. Learn to recognize these so a new repo feels familiar even when the product is not.

A repeatable strategy for an unfamiliar codebase

Do these in order the first time you open a repo you have never seen.

  1. 1

    Read the README and any docs/ folder first. It tells you what the thing is and how to run it.

  2. 2

    Run it locally. A project you can start and click through is ten times easier to understand than one you only read.

  3. 3

    Find the entry point: `main`, `index`, the server bootstrap, or the route table. Start where execution starts.

  4. 4

    Pick one real feature and trace it end to end: from the URL or button, to the handler, to the service, to the database, and back.

  5. 5

    Use search (grep / ripgrep / editor 'find in files') to jump to a symbol instead of scrolling. Search the error message, the route string, the function name.

  6. 6

    Read the tests for the area you care about. Tests are executable documentation of what the code is supposed to do.

  7. 7

    Use `git log` and `git blame` on a confusing file to see why it looks the way it does.

Tracing one feature end to end

Following a single request through the layers is the fastest way to build a mental model.

tsx
// 1. The route (edge layer): where the request enters
// src/routes/orders.ts
router.post("/orders", requireAuth, createOrderHandler);
// 2. The handler: validates input, calls the service
// src/handlers/orders.ts
export async function createOrderHandler(req, res) {
const input = CreateOrderSchema.parse(req.body); // search: CreateOrderSchema
const order = await orderService.create(req.user.id, input); // search: orderService
res.status(201).json({ data: order });
}
// 3. The service: the business logic
// src/services/orderService.ts
export async function create(userId, input) {
// ...rules live here. This is usually what you actually need to change.
return db.order.create({ data: { userId, ...input } }); // search: db.order
}
// You just learned the whole vertical slice by following ONE feature
// instead of reading 40 files in alphabetical order.

💡 Tools that make this fast

Go-to-definition (F12 in VS Code) and find-all-references jump you around without scrolling. Ripgrep (`rg`) searches the whole tree in milliseconds. The VS Code call hierarchy shows who calls a function and who it calls. `git log -p path/to/file` shows the history of just one file. Learning these four turns 'where is this even defined' from a ten-minute hunt into a one-second jump.

Common mistakes only experienced engineers catch

Reading top to bottom, file by file, instead of following one feature through the layers. Trying to understand everything before changing anything. You only need to understand the slice you are touching. Not running the project first. Reading code you cannot execute is guessing. Ignoring the tests. They tell you the intended behavior faster than the implementation does. Refactoring code you do not yet understand. Understand first, change second, or you will reintroduce the bug the weird-looking line was fixing.

Quick Check

You join a team and get assigned a bug in checkout. What do you do first?

Pick the most effective first move.

Sign in and purchase access to unlock this lesson.

Sign in to purchase
←Software Engineering vs Programming
Back to Engineering Fundamentals
Code Quality and Readability→