The Code Review Checklist: 28 Checks
Code review isn't a quality gate. It's the last moment you have to ask "should this exist at all" before it becomes someone else's problem to maintain.
馃搵 Read time: 10 minutes. Use time: every pull request.
Why This Exists
Most code review processes are theater. Someone leaves a comment about variable naming. Someone else approves because the tests pass. The PR merges. Three months later, a new engineer opens that file and has no idea what it does or why it was written that way.
Teams that ship well treat code review as a product decision, not a syntax check. They ask whether the feature is actually solving the right problem, whether the logic holds under real conditions, and whether the person who joins six months from now will be able to understand what was built without needing a 30-minute walkthrough. That is a different kind of review.
This checklist is for founders, PMs, and investors who are either doing code review themselves, overseeing engineers who do it, or evaluating teams on whether their processes are built to scale. It covers the categories that actually matter: product alignment, logic correctness, security, maintainability, performance, and process hygiene. You don't need to run all 28 checks on every PR. You need to know which checks to skip and why.
How to Use This
- Pick your role. Founders and PMs: focus on Sections 1, 2, and 7. Engineers: run the full list. Investors doing technical due diligence: Sections 4, 5, and 6 tell you the most about a team's maturity.
- Tag each check as Pass / Fail / N/A. A PR with 3 honest N/As is better than one with 28 unchecked boxes.
- Make it a shared artifact. The checklist works best when the author and reviewer both see it before the review starts. It changes what gets written in the first place.
- Revisit after incidents. When something breaks in production, trace it back to this list and find which check would have caught it.
Section 1: Product Alignment
Before reading a single line of code, ask whether the right thing was built.
- The PR description explains the why, not just the what. ("Added rate limiting to prevent abuse" beats "Added middleware.")
- The feature or fix maps to a specific ticket, user story, or decision that was agreed on before work started.
- Scope creep is absent. The PR does one thing. If it does three things, it should be three PRs.
- Edge cases that were flagged in planning are handled, or there is a documented reason they are deferred.
- Any UX-facing changes match the approved design. No improvisation in the UI without a decision record.
Section 2: Logic and Correctness
The code does what it claims to do, under conditions that actually exist.
- The happy path works. (This sounds obvious. Run it manually if you can.)
- The unhappy path is handled. Null inputs, empty arrays, missing fields, unexpected types: each should either fail gracefully or raise a clear error.
- Conditional logic is correct. Flip the conditions in your head and confirm the outcome is still right.
- Loops and recursion have a guaranteed exit condition.
- State mutations are intentional. If something is changed in place, it should be on purpose, not by accident.
- Return values are used. Silent failures (a function returns an error and the caller ignores it) are some of the hardest bugs to trace.
Section 3: Tests
Tests are documentation that runs. If the tests are missing or weak, the documentation is incomplete.
- New functionality has tests. Not 100% coverage as a religion, but the core behavior is tested.
- Tests cover at least one failure case, not just the success path.
- Tests are readable. A test that requires 10 minutes of context to understand is a test that will get deleted instead of fixed when it breaks.
- Tests are not testing implementation details. If a test breaks every time you refactor without changing behavior, the test is testing the wrong thing.
- Flaky tests are flagged, not ignored. A test that passes 80% of the time is worse than no test.
Section 4: Security
Security issues do not announce themselves. These are the categories most teams skip under deadline pressure.
- User inputs are validated before being used in queries, file operations, or external calls. The attack surface is whatever you accept from the outside world.
- Secrets (API keys, tokens, credentials) are not in the code. Not in comments. Not in test files. Not in environment variable names logged to console.
- Authentication and authorization are checked on the server, not just the client. Hiding a button is not the same as preventing the action.
- Error messages shown to users do not expose internal details (stack traces, schema names, file paths).
- Any new dependency has been checked. Not a full audit, but: Is it maintained? Does it have known vulnerabilities? Is it used by enough people that problems surface quickly?
Section 5: Performance
Performance problems are usually architectural, not algorithmic. These checks catch the architectural ones early.
- Database queries inside loops are absent. N+1 queries are the most common production performance problem and one of the easiest to spot in review.
- Large data sets are paginated, not returned in full.
- Expensive operations (API calls, file reads, complex calculations) are not repeated when they could be done once and passed through.
- Caching is used where appropriate, and cache invalidation logic is correct. If you are not sure, flag it.
Section 6: Maintainability
Code is read far more often than it is written. Optimize accordingly.
- The code is understandable without the PR description. Names are clear, functions do one thing, and complex logic has a comment explaining the reasoning (not the mechanics).
- No dead code was introduced. Commented-out blocks, unused variables, and unreachable branches all add cognitive load for the next reader.
- Repeated logic is extracted, not duplicated. If the same block appears twice, it will appear a third time and the three versions will diverge.
Section 7: Process Hygiene
The meta-layer. These checks apply regardless of what the code does.
- The PR is a size a human can actually review. If it is more than 400 lines of meaningful logic, it should have been split earlier.
- CI is green before review. A reviewer's time should not be spent catching failures a computer already caught.
- The author responded to all prior review comments, or explicitly resolved them with a reason.
Common Pitfalls
Approving because the tests pass. Tests prove the code works in the scenarios the author imagined. Review exists to add scenarios the author did not imagine.
Leaving vague comments. "This looks off" without a suggestion or question is not useful feedback. It creates anxiety without direction. Be specific about what concerns you and why.
Reviewing style instead of substance. Formatting, naming conventions, and import order belong in a linter config, not a code review. If your linter would catch it, do not spend review time on it.
Treating every PR as equal. A one-line config change and a new payment flow are not the same risk. Calibrate depth of review to depth of consequence.
Skipping context when reviewing security. It is not enough to know that something is validated. Know where it is validated and confirm it is validated before the value is used, not after.
Merging under social pressure. "It's blocking the launch" is not a code review outcome. A rushed review is not a review. It is a signature on something you have not read.
Never giving positive feedback. Code review is the fastest way to build or erode engineering culture. If something is genuinely well done, say so. It calibrates the team to what good looks like.
Why We Built This
At ProductOS, we believe the most expensive problems in software are not the ones in production. They are the ones that get into production because the review process was focused on the wrong things. Most reviews catch style. The ones that protect teams catch product misalignment, security assumptions, and architectural shortcuts that compound over time.
This checklist is a simplified version of how we think about quality across the full product lifecycle, from the moment a feature is defined to the moment code ships. The context that goes into a good product decision should travel all the way through to a good code review. When it does, review gets faster, not slower, because the hard questions were already answered upstream.
If any of this lands and you want to see it in action, we're at productos.dev. No pressure. The toolkit stands on its own.
If you'd rather have humans plus AI run this for you on a real product today, that's what 1Labs AI does.
Built by Heemang Parmar, Founder & CEO of ProductOS. 10+ years in product, 150+ builds. Also runs 1Labs AI, an AI product development agency.