Code review checklist: what to check in every PR
Zihua Li · · 9 min read
A pull request is open, the diff is 400 lines, and the reviewer has twenty minutes. Without a checklist, the review drifts toward whatever is easiest to see: names, formatting, a stray log line. The questions below keep attention on design, behavior, tests and security, and the last section shows how to hand the repeatable ones to an automated reviewer.
A code review checklist is a short list of questions a reviewer answers for every pull request: does the change do what it claims, is it designed to fit the codebase, is it tested, is it secure and fast enough, and can the next person read it. Leave formatting and lint to CI so people review only what needs judgment.
What a code review checklist is for
Reviewers forget the same things for the same reasons: a large diff, an urgent fix, a change in an area they don’t know well. A checklist makes the review repeatable, so two reviewers look at the same things and a new teammate knows what the team expects.
Google’s engineering practices put the bar in one sentence: approve a change once it definitely improves the overall code health of the system, even if it isn’t perfect. A checklist serves that bar. It helps the reviewer find what would make the codebase worse, while minor preferences stay optional.
A good code review checklist separates what tools check from what needs judgment. Formatting, lint, type errors, the build and the test suite belong in CI, where they run on every commit. The human checklist covers design, behavior, edge cases, test quality, security and readability: questions a reviewer answers by reading the change.
The code review checklist, by area
Copy the areas that fit your codebase and drop the rest. Each item is a question with a yes or no answer for the change in front of you.
Design
- Does the change belong in this part of the codebase, or in a library or service?
- Does it fit the existing architecture and patterns around it?
- Is it as simple as the problem allows, without building for needs nobody has yet?
- Does it reuse existing helpers instead of adding a parallel version?
- Is the pull request one logical change, small enough to review in one sitting?
Correctness
- Does the code do what the description and linked issue say it should?
- Are edge cases handled: empty and null values, zero, very large inputs, time zones?
- Are errors handled where they can occur, with a useful message and the right status?
- Is shared state safe under concurrency, retries and a job that runs twice?
- Do callers of a changed function still get what they expect?
- Are database migrations backward compatible with the code still running?
Tests
- Is new or changed behavior covered by a test that would fail without the change?
- Do tests check outcomes rather than implementation details?
- Are the edge cases from the correctness list tested?
- Is a bug fix accompanied by a test that reproduces the bug?
- Are tests deterministic, without sleeps, real network calls or shared state?
Performance
- Does a loop make a database query or network call per item (an N+1 query)?
- Do new queries filter and sort on indexed columns?
- Is work done once that could otherwise repeat on every request or render?
- Are files, connections and streams closed, and are caches bounded?
- Does a list endpoint paginate instead of loading every row?
Readability and maintainability
- Do names say what things are in the language of the domain?
- Can a teammate follow each function without the author explaining it?
- Do comments explain why, not what the code already says?
- Is dead or commented-out code removed?
- Is the code consistent with the conventions of the files around it?
Documentation
- Does the pull request description explain what changed and why?
- Are the README, API docs and changelog updated where behavior changed?
- Are new configuration options, environment variables and flags documented?
- Are public functions and types documented where the codebase expects it?
AI-generated code
Coding agents write code that looks finished, which makes some mistakes easier to miss. When an agent wrote part of the change, add these questions:
- Do the functions, imports and options it calls exist in the versions you use?
- Did it stay within the task, or also edit files the task didn’t need?
- Do the tests check the intended behavior, or only what the code happens to do?
- Did it add a helper, dependency or abstraction the codebase already has?
- Did it weaken a check, skip a test or catch an error just to make CI pass?
- Is it longer than it needs to be for what it does?
A reviewer that didn’t write the code catches more of these than the agent reviewing itself. See how HeyDeer reviews pull requests from coding agents.
Secure code review checklist
Every review should ask the security questions below. The OWASP Secure Code Review Cheat Sheet groups the same ground into input validation, authentication and sessions, authorization, cryptography, business logic, configuration and monitoring; use it for a deeper review of security-sensitive changes.
- Input validation. Is every external input validated on the server, with an allowlist where possible? Are queries parameterized and output encoded for its context?
- Authentication and sessions. Are passwords hashed with a modern algorithm, sessions invalidated on logout, and sensitive actions re-authenticated?
- Authorization. Does every new endpoint or action check that the caller may act on this specific object, on the server, with access denied by default?
- Secrets. Are keys, tokens and passwords kept out of the code, the logs and error messages?
- Cryptography. Does the change use established libraries and secure randomness instead of custom schemes?
- Business logic. Can a step in a workflow be skipped, repeated or raced, for example by calling the API directly?
- Dependencies. Is each new dependency needed, maintained and free of known vulnerabilities?
- Logging. Are security events logged, and is personal data kept out of log lines?
The most useful secure code review question is usually about authorization: does every new route check that this caller may read or change this specific record? Scanners find injection patterns and leaked keys well, but only a reviewer who knows the data model can tell whether a query is scoped to the right account.
A short checklist for small pull requests
For a small change, such as a bug fix, a copy change or a dependency bump, five questions cover most of what matters:
- Does it do what the description says, and nothing else?
- What happens with empty, missing or unexpected input?
- Is there a test that fails without the change?
- Does it touch authorization, user data, secrets or money?
- Would a teammate understand it in six months?
If the answer to the fourth question is yes, switch to the full security list. Authors can run the same five questions before they request review.
Where each checklist item belongs
A checklist works best when each item lives where it is checked most reliably. Tools catch the mechanical items on every commit; written rules carry what is specific to your codebase to every reviewer, human or AI.
| Kind of item | Example | Where it belongs |
|---|---|---|
| Mechanical | Formatting, lint, types, build, test suite passes | CI, required before merge |
| Coding convention | Which helper to use for dates or database access | AGENTS.md, read by coding agents and reviewers |
| Review guidance | What to leave alone, how serious a kind of issue is | REVIEW.md |
| Costly requirement | API handlers scope queries to the caller’s workspace | A repository check in .agents/checks |
| Judgment | Is this the right design for the product? | The human reviewer |
How to turn a checklist into REVIEW.md rules
Generic items, such as “check for null handling”, are already part of any competent review. The items worth writing down are the ones only your team knows: which log fields count as personal data, which paths CI already covers, which kinds of issue are serious for you. Put those in a REVIEW.md at the repository root. HeyDeer reads it on every review, and so does Claude Code Review, so one file serves both.
# Review instructions
## Always check
- Log lines don't include email addresses, account IDs or
request bodies.
- New endpoints in src/api/public/ are listed in openapi.yaml.
- Code written by a coding agent only calls functions that
exist in the pinned dependency versions.
## Leave alone
- Formatting and lint issues. CI enforces them.
- Code in tests/fixtures/ that breaks production rules on purpose.
## Severity
- A migration that isn't backward compatible is High.
- Naming and refactoring suggestions are Low.A directory with its own rules can have its own file, such as src/payments/REVIEW.md, which adds to the root file for changes below it. Keep coding conventions in AGENTS.md instead, so the agents that write code follow them too. The REVIEW.md reference covers nested files and how severity rules map to HeyDeer’s Critical, High, Medium and Low.
How to turn a checklist item into a repository check
Some items are too costly to miss to leave to a general review, such as access control on API routes or the signature check on a webhook. Make each of those a repository check: a Markdown file in .agents/checks/ whose frontmatter lists the files it covers. HeyDeer verifies it in every pull request that changes those files, with a reviewer dedicated to that one requirement.
.agents/checks/webhook-signature.md
---
files:
- "src/webhooks/**/*.ts"
- "!**/*.test.ts"
---
# Webhook handlers verify the signature first
Every webhook handler must call `verifySignature(req)` before it
reads the body or changes any data. Without it, anyone who knows
the URL can send fake events.
Fail when a handler reads the body or writes data before
`verifySignature` succeeds.
Pass when the handler returns early on a failed signature.Write one requirement per check, say what breaks it, what satisfies it and why it matters, and limit files to where it can break. When code breaks a check, HeyDeer reports a finding that names the check’s file. Each check uses its own reviewer and more credits, so keep checks for the few items that matter most and leave the rest in REVIEW.md. The repository checks guide has the full format and file pattern rules, and code review rules in HeyDeer shows how the pieces fit together.
How to keep a checklist useful
- Start from real misses. Add an item when a bug that reached production or a recurring comment shows the team keeps overlooking something.
- Prune it. Remove items that CI now enforces or that no review has needed in months. A checklist nobody finishes gets skimmed.
- Make items specific. “Handlers in src/api/ scope queries to the workspace” gets checked; “code is secure” doesn’t.
- Label what blocks. When you comment, say which issues must be fixed before merge and which are optional. Our guide to code review comments and what nit means covers the labels teams use.
For what an AI reviewer catches and misses against a checklist like this one, see how AI code review works.
Sources
Frequently asked questions
What should be included in a code review checklist?
Questions about design, correctness, tests, security, performance, readability and documentation, written so a reviewer can answer each with yes or no for the change in front of them. Add a section for AI-generated code if coding agents write part of your pull requests, and leave formatting and lint to CI.
What are the 7 steps of code review?
A common sequence is: read the description and linked issue, look at the change as a whole, review the design, check correctness and edge cases, check tests, check security and performance, then leave comments marked as blocking or optional and approve or request changes. Teams name the steps differently, but the order goes from big picture to detail.
How long should a code review take?
Long enough to answer the checklist for the whole diff. Small pull requests are what keep reviews quick: a change that does one thing can be reviewed in one sitting, while a large one gets skimmed. If a pull request is too big to review carefully, ask for it to be split.
What is a secure code review checklist?
A list of security questions for each change: is input validated on the server, does every new endpoint check authorization, are queries parameterized, are secrets kept out of code and logs, and is cryptography handled by established libraries. OWASP’s Secure Code Review Cheat Sheet groups these checks by area.
Should the author use the checklist too?
Yes. An author who runs through the short checklist before requesting review catches the obvious misses, such as a missing test or a debug log, and the reviewer can spend the review on design and behavior instead.
Should code style be part of a code review checklist?
Only the parts a tool can’t check. Formatters and linters enforce layout and many naming rules on every commit, so keep style out of the human checklist and focus it on whether names are clear and the code is consistent with its surroundings.
How do you review AI-generated code?
Review it like any other pull request, then check what coding agents tend to get wrong: calls to functions or options that don’t exist, tests that only confirm the code’s own behavior, changes outside the task, and new helpers that duplicate existing ones. Having a reviewer other than the agent that wrote the code helps.
Can an AI code reviewer follow my team’s checklist?
Yes, if you write the checklist where the reviewer reads it. HeyDeer reads review guidance from REVIEW.md and AGENTS.md, and verifies each requirement in .agents/checks on every pull request that changes the files it covers.



