The Art of Code Review: What Senior Engineers Actually Look For

Code reviews are not about catching typos. Here is what experienced engineers focus on and why it makes teams dramatically more effective.

A
AI Brains

March 10, 2026 · 4 min read · Updated March 15, 2026

Beyond Syntax

Junior developers often think code review is about catching bugs. Missing semicolons, wrong variable names, off-by-one errors. Automated tools handle most of that. The real value of code review lies elsewhere.

Senior engineers review code for three things that linters cannot catch: correctness of approach, long-term maintainability, and knowledge sharing.

What to Look For

1. Does It Solve the Right Problem?

The most expensive bug is a correct implementation of the wrong solution. Before reading a single line of code, understand:

  • What problem is this PR solving?
  • Is this the simplest approach that could work?
  • Are there edge cases the author has not considered?

A ten-line fix to the right problem is worth more than a hundred-line implementation of the wrong one.

2. Failure Modes

Every system has a happy path and many unhappy ones. For each code change, ask:

  • What happens when the database is slow?
  • What happens when the input is unexpectedly large?
  • What happens when this is called concurrently?
  • What happens when a downstream service is unavailable?
// This looks correct but fails under concurrency
async function getOrCreate(key: string): Promise<Entity> {
  const existing = await db.find(key);
  if (existing) return existing;
  return await db.create({ key, value: defaultValue });
}
 
// Two concurrent calls can both pass the find check
// and both try to create, causing a duplicate key error

The fix is often simple — a unique constraint, an upsert, or a distributed lock — but only if someone asks the question during review.

3. Abstractions

Bad abstractions are worse than no abstractions. Watch for:

  • Premature abstraction: Creating interfaces or base classes for things that only have one implementation
  • Wrong boundaries: Abstractions that group things that change independently, or split things that change together
  • Leaky abstractions: When the caller needs to know implementation details to use the API correctly

The best test: can you explain what this abstraction represents in one sentence without using the word "and"?

4. Naming

Good names are documentation you cannot skip. Look for:

  • Functions that do what they say: processData() tells you nothing; calculateMonthlyRevenue() tells you everything
  • Boolean names that read as questions: isValid, hasPermission, shouldRetry
  • Consistent vocabulary: If the codebase says "user," do not introduce "account" for the same concept

5. Test Quality

Tests that pass are not necessarily good tests. Check:

  • Do they test behavior or implementation? (Behavior survives refactoring; implementation does not)
  • Are the assertions specific enough? (expect(result).toBeDefined() proves nothing)
  • Do they cover the edge cases identified in the failure mode analysis?
  • Can you understand what the code should do by reading only the tests?
// Bad: tests implementation
test("calls database.save", async () => {
  await createUser(userData);
  expect(database.save).toHaveBeenCalledWith(userData);
});
 
// Good: tests behavior
test("creates a user with the given email", async () => {
  const user = await createUser({ email: "[email protected]" });
  expect(user.email).toBe("[email protected]");
  expect(await findUser(user.id)).not.toBeNull();
});

How to Give Feedback

Be Specific

Not: "This could be better." But: "This query fetches all columns but only uses three. Selecting specific columns would reduce memory usage and network transfer."

Distinguish Must-Fix from Nice-to-Have

Use a consistent prefix:

  • Blocking: Must be addressed before merge
  • Suggestion: Would improve the code but not required
  • Nit: Trivial style preference, take it or leave it
  • Question: Genuine curiosity, not a change request

Ask Questions

"Why did you choose X over Y?" is more productive than "You should use Y." The author might have context you lack. Questions also teach the reviewer.

Acknowledge Good Work

When you see something clever, elegant, or well-tested, say so. Positive feedback reinforces good practices and makes the process less adversarial.

The Meta-Game

The best code reviewers are not the ones who find the most bugs. They are the ones who:

  1. Raise the bar gradually: Each review makes the codebase slightly better
  2. Spread knowledge: After reviewing their PRs, team members internalize the patterns
  3. Build trust: Consistent, fair, specific feedback creates psychological safety
  4. Catch systemic issues: Individual PRs reveal patterns — if every PR has the same problem, the team needs a convention, not more review comments

Code review is not a gate. It is a conversation. The goal is not to prove you are smarter than the author. The goal is to ship better software, together.