The founder stared at the codebase on his screen. Three years of work. Hundreds of files. Thousands of commits. And he had no idea what any of it did.
"We acquired this startup," he explained. "Six months of work. The code is supposed to be the core asset."
He clicked through files randomly. Controllers. Services. Models. Repositories. The architecture looked sophisticated. Clean, even.
But when I asked him what the main business logic was, he couldn't tell me. When I asked what would break if he changed a particular file, he didn't know. When I asked how long it would take to add a new feature, he guessed.
That's the problem with inherited codebases. They look fine until you try to do something with them.
What You're Really Evaluating
Before you dive into the code, understand what you're actually trying to learn.
You're not trying to understand every line. That's impossible and unnecessary.
You're trying to understand:
- Can you maintain this? Will you be able to fix bugs and make changes?
- Can you extend this? Can you add new features without everything breaking?
- Can you trust this? Does it do what it's supposed to do?
- What's the real state? Is this healthy code or is it hiding problems?
These questions don't require reading every file. They require strategic investigation.
Where to Start
Start #1: Try to Build It
The first thing I do with any new codebase: try to run it locally.
If you can't get the development environment running, that's a red flag. A healthy codebase should have clear setup instructions. Dependencies should be documented. The process should work.
I once spent three days trying to get a startup's codebase running locally. Three days. The documentation was outdated. The setup instructions were wrong. The required secrets weren't documented.
When I finally got it running, the app crashed immediately. No one had noticed because no one had tried to run it in months.
If the developers can't run their own code locally, that's a problem.
Start #2: Run the Tests
What tests?
I look for a test directory. I try to run the tests. I see what coverage looks like.
A codebase with good tests is a codebase you can trust. Even if the code is complex, tests tell you what the expected behavior is. They give you confidence when you make changes.
A codebase without tests is a codebase where someone is afraid to change things. Because they don't know what will break.
I've reviewed codebases where the test suite didn't run at all. The tests were written once, passed once, and never touched again. They were useless—but they made the coverage numbers look good.
Look past the numbers. Do the tests actually work? Do they test meaningful behavior? Can you trust them?
Start #3: Look at the Logs
Not system logs. Git logs.
I read the commit history. Not every commit—too many. But the patterns.
Who commits? When do they commit? How big are the commits? What messages do they write?
I've learned more about codebases from commit messages than from code reviews.
A healthy codebase has:
- Regular commits from multiple people
- Descriptive messages that explain why, not just what
- A steady stream of small improvements
A troubled codebase has:
- Long gaps with no commits
- One person doing most of the work
- Messages like "fix" or "wip" or "again"
What to Look For
Look For #1: Test Patterns
Tests tell you what's important. Find the test files. See what's being tested.
I look for tests of business logic. Tests of edge cases. Tests of the core features.
If the tests only cover trivial things—like utility functions, or trivial components—that tells you where the confidence is. And where it isn't.
A startup I reviewed had 90% test coverage. Impressive numbers. But they were testing their CSS. Their business logic had no tests.
Coverage metrics lie. Patterns don't.
Look For #2: Error Handling
Find a place where something might go wrong. A network call. A database query. User input.
See what happens when it fails.
I've reviewed codebases where errors were swallowed. try { } catch {} with nothing inside. Functions that return null without explanation. Operations that fail silently.
These are the bugs that surface at 2 AM. The ones that break things and leave no trace.
Good code fails loudly. It logs errors. It notifies someone. It makes problems visible so they can be fixed.
Look For #3: Documentation
Find the README. Read it. Is it accurate?
Then find the code documentation. Comments in the code. Architecture decisions documented. API specifications.
I've reviewed codebases where the README hadn't been updated in two years. It described a system that no longer existed.
Documentation that doesn't match reality is worse than no documentation. It misleads you. It makes you confident in things that aren't true.
Look for documentation that evolves. Recent updates. Links to actual code. Examples that work.
Look For #4: Dependency Health
Look at the package.json or equivalent. Or Gemfile or requirements.txt.
When were dependencies last updated?
I've seen codebases running libraries with known security vulnerabilities. Libraries that were abandoned years ago. Libraries that don't work with modern versions of the language.
Dependencies are someone else's code that you rely on. When those dependencies rot, your code rots with them.
A healthy codebase updates dependencies regularly. An unhealthy one accumulates technical debt in its dependencies.
The Red Flags
Some things are deal-breakers. Look for these:
Red Flag #1: Logic in the Wrong Place
I reviewed a startup's codebase once and found business logic in controller actions. All of it. Every business rule, every validation, every workflow—dumped directly into controllers.
That means you can't change anything without understanding every path through the UI. It means testing is nearly impossible. It means the code is tightly coupled to a specific interface.
Clean architecture separates concerns. Business logic belongs in business logic layers. The code should be testable without starting a web server.
Red Flag #2: Duplication Everywhere
I found the same function copied into seven different files in one codebase. Slight variations each time. No one knew which version was correct.
Copy-paste is the enemy of maintainability. When you change something, you have to change it everywhere. And you never know if you got them all.
A healthy codebase has abstractions. Common logic extracted into shared utilities. Patterns that are followed consistently.
Red Flag #3: No One Can Explain It
Ask someone on the team to explain how a feature works. See how long it takes them to get confused.
I've asked developers to explain their own code and watched them struggle. They couldn't trace the execution path. They didn't know where the data came from. They were flying blind.
If the people who built it can't explain it, you won't be able to either.
Red Flag #4: Fear of Change
Ask: "How long would it take to change X?"
If the answer is "a long time" or "we'd probably rewrite it," that's a problem.
Healthy codebases accommodate change. Unhealthy ones resist it.
Look for evidence of recent changes. Has anything been refactored lately? Has anyone cleaned anything up? Or is everything just accumulating complexity?
The Questions to Ask
After you've done your investigation, ask these questions:
Question 1: Can a new developer be productive in a week?
If the answer is no, the codebase has onboarding problems. This shows up in time-to-productivity. It shows up in how long it takes new hires to contribute.
Question 2: Can you deploy without fear?
If the answer is no, the codebase has reliability problems. Every deployment should be relatively safe. If you're afraid to ship, something is wrong.
Question 3: Can you find the code you're looking for?
If the answer is no, the codebase has organization problems. You shouldn't need a treasure map to find where something is implemented.
Question 4: Can you understand what the code does?
If the answer is no, the codebase has communication problems. Code is communication—between developers, across time. If it doesn't communicate, it's not doing its job.
The Bottom Line
Evaluating a codebase you didn't build isn't about understanding every line. It's about understanding the patterns. The health indicators. The risks.
Look for evidence of care. Look for signs of maintenance. Look for clarity in the places that matter.
And when you find problems, don't panic. Every codebase has problems. The question is whether the problems are fixable, and whether the people who built it are willing to fix them.
A codebase with obvious problems and an aware team is better than a codebase that looks fine and has hidden rot.
The goal isn't perfection. It's understanding what you're inheriting—and what it will take to make it work.
Need Help Evaluating a Codebase?
At Startupbricks, we help startups assess code they didn't write—before they acquire it, before they inherit it, before they regret it.
If you're facing a codebase you don't understand, let's take a look together.
