by Phil Miller
Code reviews are a crucial part of a healthy software development organization at any size, and in many cases they are an organizational or regulatory requirement.
Let’s unpack how to level up your code reviews and create the best possible experience for everyone involved.
In this post we’ll cover the following:
- Why we do code reviews
- What to consider before you start
- Best practices for code reviews
- Post-review tips
- Tips for the author
- Code review tools
Why do code reviews?
In this modern, fast-paced world of software development it may seem counterintuitive to have all your code reviewed when you could just be shipping it. However, software development is best viewed as a team sport, so why not get some teammates involved? Ultimately, the goal of writing code is to ship some unit of business value (ex. a new feature, an important bugfix) and to introduce as little technical debt as possible while doing so. Code reviews are the best way to achieve this goal.
We do this by:
- ensuring code quality and coding standards
- catching and fixing those elusive bugs before they ship
- sharing knowledge across our teams
Being a prolific contributor is great, but if your bus factor is 1, you are still creating undue risk for your current and future teammates. Code review is a great way to improve all of the above because it forces you to have discussions and create new shared context.
Before you review
One of the most important, and often overlooked, aspects of a code review is understanding that you are providing feedback about the code and not the coder. At the same time, it’s equally important that you acknowledge that the person who is receiving this feedback is a real person with real feelings. So, the default mindset should always be one of positivity. Your ultimate goal is to help the coder, and your development organization at large, to improve, and that feedback is much more likely to land well if it comes from a positive starting point.
Now that you are in the right mindset, it’s time to get the appropriate context. What are the expectations around the code being reviewed (for example, what is this feature supposed to do, what are the specifications, what are the use cases it must handle) and what kind of supporting documentation exists for this code. Hopefully the author (or any automated tooling) has already provided some valuable links to things like: a ticket in your system of choice (ex. Linear, JIRA, GH Issues), design files (ex. Figma, Invision, Sketch), and any related PRs or commits. If not, then you may have to ask for this.
Lastly, you want to consider the “chunks” you hope to review and limit them to sizes that are digestible. In a perfect world, the author has already done this and you have a right-sized chunk of code for review. Sometimes, unfortunately, large reviews are unavoidable, so you, as the reviewer, will need to figure out what an appropriate chunk of code is for each part of your review. If code reviews end up taking multiple hours, then that’s an indication that the chunks are too large or that there may be other problems in the development process.
Best practices for code reviews
Ok, you’ve put yourself in the right mindset. You’ve read all the supporting docs, and you’ve considered the best way to split up the review into digestible chunks.
You’re ready to dig in.
First, you want to have a high level understanding of this set of changes. Go through the files and think about the overall structure and flow. Only when you’ve done that once (or twice!) then think about digging a bit deeper. As you do it’s best to consult a checklist to keep things structured. Consider the following:
- Coding standards and best practices
- What are the expectations within our organization and team?
- Does this code follow them?
- Does it modify them?
- Is this necessary?
- Error handling and logging
- Are the log levels appropriate (Info, Warn, Error, etc)?
- Are the messages meaningful and identifiable?
- What are the expectations for test coverage?
- Does this code have appropriate coverage?
- Are the types of tests appropriate (e.g. unit tests vs integration tests)?
> Each of these items on the checklist probably warrant its own article, and we will explore them in future posts!
Now you’ve done a thorough review of the code and you’ve found a few things that are worthy of feedback. The most actionable way to approach this is by leaving constructive comments. What is a constructive comment, you ask? Keeping in mind the positivity we discussed previously, a constructive comment should:
- Be clear and specific
- Ask questions instead of being instructive
- Suggest alternatives (actionable feedback is king)
- Identify its own importance (ex. Nitpick vs blocker)
- Not bikeshed
Next, considering all of your feedback in aggregate, it’s often best to provide a summary, such as a general PR comment summarizing the overall feedback and major items to be addressed. This general PR comment is especially important if there are any cross-cutting themes or common issues across comments (for example, an issue that happens or an architectural refactoring impacting many different files) . Sometimes this can happen entirely async, but other times it may be easier to have a quick call (or meeting), to provide more clarity. You could even do some pairing to shorten feedback cycles on any actionable comments and work through them together.
Lastly, once both author and reviewer agree that feedback has been resolved, consider any lessons learned and share them with your team(s) so that everyone can benefit.
Tips for code authors
As mentioned before, software development is a team sport. So, as the author of the code, you need to think about setting up your reviewers for success. As mentioned in the “Before…” section, make sure you are providing all the necessary context in the form of supporting documentation (tickets, design assets, other PRs) and providing any general context in a summary comment. If the PR is in a good condition, it’s often a good idea to let the submitter know that they’ve done a good job and that you appreciate their effort.
Since your reviews should be coming from a place of positivity, you need to mirror that mindset. The whole point of this process is to ship better code through feedback, not to point out mistakes. Speaking of feedback, it’s your job as the author to address any feedback that requires follow-up and to do so in a timely manner. A reviewer’s attention is most likely divided, so the faster the feedback cycles can be, the more likely the reviewers are to retain the necessary context.
Code reviews are the foundation of any modern software development practice. They serve to lower the amount of defects that teams ship both immediately and in the future. They also provide a means for continuous context sharing and learning for all current and future members of a team.
Hopefully, the concepts outlined here have helped you to think about how you might improve your code review process. If there’s anything we missed, feel free to drop us a line on Linkedin.
If you want to level up your team and do better code reviews with AI, please check out the Korbit AI Mentor and let us know what you think. We value your feedback!