Read or buy our book, Build: Elements of an Effective Software Organization →

A complete guide to code reviews

Kimmo Brunfeldt, Software Engineer · May 12, 2025

Code reviews are a widely accepted best practice for software development teams. In this guide, we’ll cover why the most successful teams use code reviews, how to adopt them in your development process, and what we believe the current best practices are.

Author's note: We first published this guide in late 2021, but we've given it a refresh with some extra tips and best practices in May 2025.

Why do we need code reviews?

Everyone benefits from code reviews — no matter whether you’re a 10x developer or a fresh graduate. The goals of code reviews are, in general:

  • Sharing knowledge: The depth of know-how shared depends on the thoroughness of the review, but some amount of information will always be transferred. The knowledge can be general tips about the framework or programming language or invaluable domain-specific information bits.
  • Spreading ownership: Code reviews have a positive impact on mutual code ownership. It’s easy to end up in a situation where one developer always deals with a certain part of the codebase because they’re most familiar with it. It might be a short-term win but is often a long-term loss. When ownership is shared, teams become more motivated and autonomous.
  • Unifying development practices: Every developer has their own tendencies and ways to implement software. Code reviews help to narrow the gap between individual development styles and make the codebase more unified. Unification happens through high-level discussions about architecture and software design and via micro-level continuous integration checks, such as coding style enforcement.
  • Quality control: Studies have shown that code reviews can help with catching defects, but even more importantly, they surface software design issues while they are still relatively easy to change.
The four whys of code reviews
The four whys of code reviews

Adopting code reviews

It’s crucial to set the review process right. At worst, code reviews might feel like a hindrance. At best, code reviews help to sustain good, stable team performance for many years.

If your organization is new to code reviews, introducing them will be a big change in the development process. Whenever implementing changes to ways of working, it’s a good idea to make sure that everyone agrees on the process and has had the chance to contribute to the decision — if you do this, I promise there will be less friction.

You, as a team or an organization, should agree on the philosophy and motivation behind code reviews before implementing them. You can write down an internal “what’s a good code review” document together or refer to existing guides. It’s a practical way to make sure everyone is aware of the whys.

Also, we can’t ignore social relationships when talking about peers giving feedback about each other’s work. There are no silver bullets. It’s hard work that requires each individual’s contribution. And to have the best chance of success, make sure to thoroughly discuss and educate your team about communication practices.

Best practices for code reviews

You might read other blog posts about code review best practices that focus on smaller details about branch names, commit message lengths, etc. While those tips are valuable too, this post focuses on more general recommendations.

There are multiple perspectives to a code review process: the author’s, the reviewer’s, and the team’s point of view. Each party has an equally important role in the process. Some best practices apply only to the author or the reviewer, but many of them are important for everyone in the team.

Let’s go through what those best practices are. We’ll focus on GitHub and pull request (PR) oriented review processes, but many of the tips apply in general as well.

1. Decide on a process

Responsibility will bounce between the author and the reviewer(s). The more explicit the review process, the less likely the ball is dropped by any party.

For example, our internal PR guidelines look something like this:

  1. DRAFT You can open a PR in a draft state to show progress or request early feedback.
  2. READY FOR REVIEW You can also skip the draft state and open a PR directly.
    • Usually, there’s no need to request a review; Swarmia automatically notifies the team via Slack. A manual review request can be useful if you, for example, want to request a design review from a certain designer.
    • The review is done by another team member or a developer who is particularly familiar with the part of code base that was changed.
    • It’s polite to have the PR ready so that you’re not about to rebase everything 5 times while the reviewer tries to keep up.
  3. CHANGES REQUESTED Fix the requested changes, or discuss whether a fix is needed.
    • Preferably, create new commits after the review.
    • You can also directly commit suggestions from the GitHub UI.
  4. APPROVED The author is responsible for merging their own PR.
Sketch of our internal process
Sketch of our internal process

Your pull request guidelines might look different, but as long as the team agrees on the process, it’s all good.

2. Focus on the right things

To maintain code review standards across developers, it’s a good idea to have guidelines for what to focus on in code reviews. Here’s what we recommend focusing on:

  • Functionality: Does the code behave as the PR author likely intended? Does the code behave as users would expect?
  • Software design: Is the code well-designed and fitted to the surrounding architecture?
  • Complexity: Would another developer be able to easily understand and use the code?
  • Tests: Does the PR have correct and well-designed automated tests?
  • Naming: Are names for variables, functions, etc. descriptive?
  • Comments: Are the comments clear and useful?
  • Documentation: Did the author also update relevant documentation?

Developers shouldn’t spend their time reviewing things that can be automatically checked. More on that in “Use continuous integration effectively” and “Delegate nit-picking to a computer”.

3. Discuss the high-level approach early

Before jumping into coding a complex feature, it’s beneficial to discuss the high-level approach first. Usually, this is done when planning the feature.

It’s not nice for anyone if a PR ends up in a complete rewrite because the approach wasn’t discussed beforehand. Rewrites of pull requests do happen every once in a while, but it’s a sign that you might want to talk more before you get your hands dirty in implementation.

Sometimes a proof-of-concept implementation is needed to ignite the discussion. An effective way to get started is to open a draft PR of the approach and make the architecture decision based on the information you gain from that discussion.

4. Optimize for the team

This idea is explained well in Google’s Engineering Practices document:

We optimize for the speed at which a team of developers can produce a product together, as opposed to optimizing for the speed at which an individual developer can write code.

Speedy reviews increase team performance in multiple ways: iteration becomes faster, developers don’t need to do time-costly context switches as often, and nobody is left waiting around for long periods before they can continue working.

Make sure the team understands the implications of fast reviews and agrees on a suitable maximum time for responding to a PR. The key is to minimize the response lag between the author and the reviewer, even if the whole review process takes long. For example, it might be invaluable for the author to know that their PR will be reviewed, for example, tomorrow morning.

That said, developers shouldn’t interrupt their focus to do reviews. Instead, they should prioritize them whenever there’s a fitting gap — for example after lunch or before wrapping up for the day.

Review speed is definitely not solely the reviewer’s responsibility — the author has an important role too. The easier it is to pick a pull request and review it, the faster the work flows. Our help article “Review code faster” covers how to leverage Swarmia to speed up reviews.

5. Default to action

Life isn’t perfect, and sometimes reviews can stall for various reasons. During those times, you should have a bias for action. One can approve a PR even if there’s some input left for the author to consider.

If a tech decision lingers and work becomes blocked, deciding something relatively quickly is better than slowly concluding to an “ideal” decision. Reserve enough time for technical decisions, but do move on before you reach analysis paralysis. Developers should be inclined to merge code instead of primarily focusing on poking holes in the implementation.

Ship it!
Ship it!

6. Keep pull requests small

Smaller batches are easier to design, test, review, and merge. There are studies [1] [2] about the optimal amount of changed lines, but it’s not an exact science. Google’s recommendations put it well:

There are no hard and fast rules about how large is “too large.” 100 lines is usually a reasonable size for a CL, and 1000 lines is usually too large, but it’s up to the judgment of your reviewer. The number of files that a change is spread across also affects its “size.” A 200-line change in one file might be okay, but spread across 50 files it would usually be too large.

It’s almost always possible to split a large change into smaller chunks — for example, with a separate refactoring PR that sets the stage for a cleaner implementation. Practicing slicing also helps to detect minimal shippable increments of your product.

Feature gates or feature flags might be necessary to gain the ability to ship half-ready product features along with the existing ones. Learn more why small pull requests are better.

keep prs small

7. Foster a positive feedback culture

Effective communication, in general, is really hard. Giving feedback about a colleague’s work is one of the most challenging forms of communication. Acknowledge this in code reviews.

Here’s a list of suggestions to improve discussions in code reviews:

  • Give feedback about the code, not about the author.
  • Pick your battles.
  • Accept that there are multiple correct solutions to a problem.
  • You’re in the same boat.
  • PR authors are humans with feelings (except dependabot 🤖).
  • Provide reasons, not feelings, to support your position.
  • Use the “Yes, and...” technique to keep an innovative atmosphere. It can be an ungracious pattern to dismiss fresh and fragile ideas in a draft PR stage.
  • Keep the feedback balanced with positive comments. It’s always delightful to receive praise from a reviewer.

If the pull request discussion becomes heated, schedule a call to discuss the topic. It usually helps to relieve the tension.

8. Use continuous integration effectively

GitHub Actions and status checks are widely used for building a robust CI pipeline. However, no matter the tools, it’s worth investing in setting up a CI solution to automate as many quality checks as possible.

Automated checks allow reviewers to focus on more important topics such as software design, architecture, and readability. Checks can include tests, test coverage, code style enforcements, commit message conventions, static analysis, and much more.

A variety of metrics produced by continuous integration can help the reviewer to quantify the quality of a PR. Test coverage and code complexity metrics might reveal interesting insights that otherwise would be hard to estimate. These metrics don’t necessarily need to be hard pass or fail checks but rather additional data for the review process.

Instead of slowing down the review process to catch more bugs, try to improve the automated checks to enable fast movement.

GitHub pull request checks for Swarmia's frontend repository
GitHub pull request checks for Swarmia's frontend repository

9. Delegate nit-picking to a computer

Whenever a reviewer spends their time nit-picking on small details, consider if it could be an automated check. Automatic checks will always be enforced, while the human process relies on the reviewers’ memories and moods to reject an anti-pattern.

For example, our ESLint rules enforce a consistent usage of certain terminology across the product. This is far more effective than documentation that would list the correct spelling of each word.

Code formatting is an example of a controversial topic in which almost all solutions are correct. Spending time debating stylistic choices rarely provides much value to the product, as long as a set of rules are adopted. Consistent unpleasing styles (to some individuals) are better than a mixture of multiple styles.

Your team can also adopt pre-existing practices, for example, a TypeScript project could adopt Prettier defaults instead of re-inventing their own.

delegate nitpicking to a computer

10. Communicate explicitly

When reviewing a piece of code, be explicit about the action you request from the author. What do you want them to do as a result of your feedback?

Let’s say a reviewer has commented, “This could be done in Postgres in favor of application code” on a line of code. Are they requesting a change, suggesting to refactor it later, or just making the author aware of other solutions? It’s often hard to judge. GitHub provides tools to be more explicit: for example, “Request changes” in a review.

github request changes

Tip for the PR author: dismissing a review resets the pull request state to indicate that the reviewer can review again. It’s up to you, the PR author, to decide if it feels important enough to use the feature, but especially in remote teams, it might help to make the process even more explicit.

11. Use explicit review requests

Review requests in GitHub are a convenient way to let others know that your code is ready for review. While a review can be requested manually, we recommend setting up a CODEOWNERS file to automate requesting a review. The method is robust and doesn’t rely on individual authors remembering to request reviews.

Reviews can also be requested from a team, via CODEOWNERS or manually, which distributes the responsibility among team members. This way, you can make sure reviews are done evenly by all developers instead of siloing reviews to a single person.

Example of a CODEOWNERS file from Swarmia’s frontend repository telling GitHub to notify @swarmia/engineers team whenever a new PR is opened
Example of a CODEOWNERS file from Swarmia’s frontend repository telling GitHub to notify @swarmia/engineers team whenever a new PR is opened
Example of an email sent from a PR based on a CODEOWNERS file
Example of an email sent from a PR based on a CODEOWNERS file

12. Review your own code

Before submitting a PR for a review, go through the changes yourself. This helps to catch accidentally included changes, typos, and other simple mistakes that potentially waste the reviewer’s time.

13. Document as much as possible in code

When receiving a comment or suggestion, aim for documenting the discussion in code. If the reviewer is not sure what the validateUsers function does, elaborate on the functionality ideally by renaming the function or writing a comment in the code. This way, the next developer that reads the code will understand the functionality without reading the PR discussions.

In some cases, the author can copy-paste their PR discussion response as is to comment in the code.

14. Write clear PR descriptions

The reviewer forms a mental picture of a pull request from multiple information sources: feature planning, description in the issue tracker, PR description, commit messages, chat history, etc. The more coherent the picture is, the faster and higher quality the review is. Decide on the team’s preferred channels to communicate certain information.

At Swarmia, we use PR descriptions to fill the technical gaps that the Jira issue description didn’t cover. The additional details often include information such as what setup is needed to test the PR, surprising implementation details, and anything that makes the reviewer’s job smoother. There are also other ways to add information: code comments, commit messages, commenting on individual lines in a PR as the author, etc.

Demo in any visual form is a nice touch. The format can be a screenshot, a screen capture, terminal output pasted in a code block, or anything that captures the change well. GitHub supports both videos and GIFs in the PR descriptions.

In addition to a static demo video, it’s a great practice to build preview versions of your application per PR branch. The ability to interactively test the application preview without setting up anything in a local development environment saves time and increases the likelihood of someone manually testing a pull request.

Remember that the fidelity of descriptions required depends on the context.

The spectrum of descriptions
The spectrum of descriptions

You, as a team, need to figure out the perfect balance between explaining nothing or explaining everything.

GitHub also supports issue and pull request templates if you want to standardize parts of the descriptions.

15. Use the shared repository model

For most private repositories, we recommend starting with the Shared repository model:

In the shared repository model, collaborators are granted push access to a single shared repository and topic branches are created when changes need to be made.

This model makes many aspects of the review process in GitHub simpler than the forking model that is popular among open-source projects.

16. Keep discussions public

It’s convenient to have a quick chat about a pull request in the office, but be mindful of colleagues working remotely. It’s polite to add a summary of face-to-face discussion as a PR comment.

Pull request discussions are searchable and easily accessible by all developers. They act as a history log of discussion which might be incredibly valuable when debugging a production incident later on.

17. Use Swarmia to improve your review process

After implementing all (checks notes: 16) code review best practices above, you might still face challenges with visibility and timely notifications. This is where Swarmia helps teams maintain their review flow.

Our GitHub-Slack integration sends targeted notifications that keep code moving without interrupting focus. The notifications are designed to appear exactly when needed — after CI checks pass, when someone requests your review, or when a PR you’ve reviewed has been updated.

Swarmia's Slack-Github notifications
Swarmia's Slack-Github notifications

For engineering teams, the dedicated pull request view provides visibility into which PRs need attention, who’s waiting on reviews, and review times across the team. This visibility helps prevent work from stalling unnoticed. But honestly, the Slack notifications in our team channel are all I really use on a day-to-day basis.

Open pull request view
Open pull request view

Teams can also create working agreements around review times and receive gentle reminders when approaching those thresholds. Most teams using these features see significant reductions in their review cycle times.

The combination of timely notifications and team-wide visibility makes it much easier to maintain the review practices we covered in this guide.

Building a code review process that works for your team

Code reviews are a cornerstone of healthy engineering culture. When done well, they encourage learning, improve code quality, and strengthen team bonds (rather than becoming a source of friction or delay.)

Start with the fundamentals we’ve covered here, but don't be afraid to adapt them to your specific context. What works for a startup might differ from what suits an enterprise team, and that's completely fine.

Also, the goal isn’t to have perfect code, but to build a system where engineers learn from each other while shipping value to your end users. Sometimes that means taking a deep breath and approving code with minor suggestions rather than blocking progress, and other times it means taking the extra time for deeper architectural discussions.

Over time, you’ll find your team developing its own code review culture, with shared vocabulary and expectations that make reviews more efficient and effective. Celebrate when this happens — it’s a sign of a mature engineering organization.

That’s a wrap

Anyway, that concludes our complete guide for code reviews — thanks for sticking with me all the way until the end! I hope you’ve learned something new about code review practices, or gained a tip to try in your own team.

If you do end up implementing anything I shared in this article (or just want to discuss them) feel free to reach out.

Until then, happy reviewing!

Speed up your code reviews with Swarmia
Swarmia’s real-time Slack notifications and team-wide working agreements help you review and merge code to production up to 3x faster. Start your free 14-day trial today to learn more.
Start trial

Additional reading

Kimmo Brunfeldt
Kimmo Brunfeldt is a Software Engineer at Swarmia. In the past, he worked as a Senior Software Engineer at Aiven, consulted enterprise clients at Futurice, and co-founded Alvar Carto.

Subscribe to our newsletter
Get the latest product updates and #goodreads delivered to your inbox once a month.

More content from Swarmia
Miikka Holkeri · Oct 25, 2024

Complementing engineering metrics with developer experience surveys

Seeing engineering productivity data for the first time can be an eye-opening experience. You notice a high pull request cycle time, dig deeper into its components, and see that reviews are…
Read more
Jarno Rantanen · Jan 3, 2024

What good Continuous Integration (CI) looks like

Continuous Integration (CI) is the process of integrating work from multiple developers, and assuring its quality automatically. It’s an integral component of any modern development effort, as…
Read more