How to Do a Code Review

A 40-line diff gets read. An 800-line diff gets approved. Most review quality is decided before anyone opens the pull request.

How to Do a Code Review — Troiana insight cover

In short

A useful code review checks, in order: does this do what it claims, does it handle the cases it will actually meet, is it safe, and can the next person understand it. Style belongs to a formatter, not a reviewer. The biggest determinant of review quality is diff size — small changes get genuinely read, and large ones get approved on trust.

The order that matters

Review in this sequence. Reversing it is why reviews produce many comments about naming and miss the bug.

1. Does it do what it says? Read the description, then check the change actually delivers it. Scope creep and missing pieces are both common and both invisible if you start by reading line by line.

2. Does it handle the real cases? Empty input, missing record, duplicate request, concurrent access, failed network call. This is where genuine defects live.

3. Is it safe? Anything touching authentication, permissions, payments, user input, or deletion gets read properly rather than skimmed.

4. Can the next person understand it? Not "is it clever" — will someone unfamiliar follow it in six months?

5. Style. Last, and mostly not your job. A formatter and a linter should have settled this before the review existed.

Diff size decides everything

The uncomfortable truth: review quality collapses as diffs grow. A 40-line change gets read carefully. An 800-line change gets skimmed and approved, and everyone involved knows it.

So the highest-leverage review habit is not a technique. It is asking for smaller changes. A refactor separated from a behaviour change, so the reviewer can see what actually changed. A large feature split into reviewable steps behind a flag.

If a pull request cannot be reviewed properly, saying so is more useful than approving it and hoping.

Write comments people act on

Say what and why. "This will break when items is empty" is actionable. "This looks wrong" is not.

Separate blocking from optional. Prefix non-blocking thoughts — nit:, optional: — so the author knows what actually stops the merge. Without this, every comment reads as a demand and reviews take three rounds.

Ask when you are unsure. "What happens if this is called twice?" is better than asserting a bug you have not confirmed. Often the author has an answer, and occasionally the question finds the defect.

Comment on code, not people. "This function does two things" rather than "you always do this".

Say when it is good. Reviews that only ever contain criticism make people defensive, and defensive authors argue rather than fix.

What not to review

Formatting. Automate it. Arguing about it wastes senior time on something a tool settles.

Preferences dressed as standards. If two approaches are equally valid, the author's choice stands. Rewriting other people's code to your taste is not review.

Everything at once. A review with forty comments is a rewrite request. Prioritise: what must change, what should, what is worth mentioning.

Reviewing AI-generated code

This has changed the job, and pretending otherwise is how defects ship.

Read the diff, never the summary. The assistant's description of its change is generated text about the change, not evidence of it. The diff is the fact.

Expect plausible bugs. Human bugs tend to look wrong. Generated bugs tend to look reasonable but incorrect — the right shape, subtly wrong on an edge case, handling the happy path and quietly mishandling the empty one. They survive casual review precisely because they read well.

Check the edges the model skips. Error paths, null and empty cases, concurrency, migration and rollback behaviour.

Trace new dependencies and network calls. Assistants add libraries readily. Each one is a supply-chain decision.

Be more suspicious as diffs grow. Generated code makes large diffs cheap to produce and no cheaper to review, which is exactly the trap described above — vibe coding is safe or dangerous depending entirely on whether this discipline holds.

For the author

Most review friction is created before the review starts.

Keep it small. Write a description saying what changed and why, and what you want scrutinised. Review your own diff first — you will catch the debug statement. Separate refactors from behaviour changes. And when a reviewer misunderstands something, treat it as a signal the code is unclear rather than a failure of the reviewer.

What good looks like

A reviewer who understood the change, checked the cases that matter, and left a small number of specific comments. An author who responded to each one and pushed a focused fix. A merge that happened the same day.

What it does not look like: forty comments about naming, a two-day round trip, or an 800-line diff approved in four minutes.

If you want an outside read on a codebase before taking it on, book a call.

Common questions

What should you look for in a code review?

In order: whether the change does what it claims, whether it handles the cases it will actually meet, whether anything security-sensitive is safe, and whether the next person will understand it. Style comes last and should mostly be handled by a formatter and linter before the review exists.

How big should a pull request be?

Small enough to be genuinely read — roughly the difference between a 40-line diff that gets scrutinised and an 800-line diff that gets approved on trust. Separating refactors from behaviour changes, and splitting large features into steps behind a flag, does more for review quality than any technique.

How do you review AI-generated code?

Read the diff rather than the assistant's summary, since the summary is generated text about the change rather than evidence of it. Expect plausible-looking bugs that are subtly wrong on edge cases, check error paths and empty cases specifically, and trace every new dependency and network call.

Should code review comments block a merge?

Only some of them. Prefix non-blocking comments with 'nit:' or 'optional:' so the author can tell what actually stops the merge. Without that distinction every comment reads as a demand, and reviews stretch into multiple rounds over preferences.

Should reviewers comment on code style?

No — automate it. A formatter and linter should settle formatting before a human looks at the change, so review time goes to correctness and clarity. Preferences dressed as standards are also worth avoiding: where two approaches are equally valid, the author's choice stands.

Have something worth building right?