Codified standards can help your team be more productive
Feb 15, 2023
Over the last six months I’ve chatted with engineering managers at dozens of companies - and something has started to stand out to me - the divide between teams that do and don’t have explicit code standards and guides that the whole team needs to be following.
Of the teams I talk to maybe 30% have guidelines that they’ve put together and try to enforce. It’s not like the rest don’t have any sort of internal guidelines - they just haven’t been codified. Instead these teams are keeping track of these ideas in their heads, trying to implement them as they write and review code. But as a result, they’re not consistently followed.
All of this leads to those 30% of teams having less debate during reviews, less friction in styles and approach, and less tech debt. Because you really should have clear cut rules that all your code should follow.
Best Practices and Consistency Have Real Impact
It might seem like a given that having consistency and best practices across your codebase is a good thing. But what is the actual cost of having inconsistent code throughout your project?
Future development is going to be slowed down. If there are different styles, structures, or design patterns used in the codebase then a developer is always going to have to spend extra time to consider which way they should implement new functionality and they’ll have to untangle the logic behind why the same thing is implemented in two different ways when trying to understand the current code.
More bugs are going to be introduced. Using multiple, inconsistent, approaches is going to significantly increase bug risk throughout your project because there’s an increased risk that you miss out on covering all of the approaches used when using new functionality.
On top of this - it becomes harder to review or create test cases for multiple different approaches used across the project and makes it easier for things to fall through the cracks.
It’s harder to onboard new team members. One of the biggest hurdles in onboarding a new developer to a project is getting them up to speed in understanding the existing codebase. But, if the approaches aren’t consistent in how that code is structured then that onboarding time is going to be even longer than usual. If it's too complex onboarding can be almost impossible.
Let’s consider a few examples:
Code added later occasionally used the new name (following the user story's terminology), occasionally the old name (following the code's terminology).
Mapping between the old and new names is straightforward from a technical perspective. But for humans it’s a daunting task to remember this type of mapping all the time. It made the code more difficult to reason about, more difficult to spot connections. And easier to overlook things and introduce bugs.
In this first example we can see how naming can diverge over time without having consistent guidelines and standards. At first it might not seem like such a big deal, but as more and more of the code is using two different types of names, it becomes more and more confusing. Are the two types of names referring to the same things? Different things?
At best this type of naming issue can lead to slowdowns in future development while you’re trying to figure out what’s happening in the code and where your changes might cause side effects. At worst it could lead to significant bugs being introduced across the codebase.
In the second example we can see that having non-explicit standards around your package dependencies can easily result in unexpected bugs arising during future development.
So far in this article I’ve used a couple of terms a few times without fully defining them - specifically Best Practices and Standards. I use the two terms Best Practices and Standards interchangeably and I am referring to any rules you and your team agree should be followed across your codebase. A great first step is to use the standards that are widely accepted for your language and frameworks, e.g. PEP8 for Python. Then the next step is to also establish some rules that are specific to your project and your domain. These aren’t mutually exclusive and you’ll want to have both of these styles of rules in your project.
Having Best Practices Isn’t Enough - You Need to Codify Them
As you start to establish best practices and standards you want your team to follow you need to ensure that they’re actually being followed. Ideally your team is applying these standards while they’re writing new code, but you also need to be able to check against them throughout the development process - especially during code reviews. But, this is almost impossible if these code standards aren’t clearly codified. Without a readily available outline of how to approach and how not to approach certain situations, your team isn’t going to be able to always make sure all of your code is following these standards. By turning them into a living document, you’ve created a resource that your team can reference throughout the development process to help increase long term efficiency.
A quick note - I’m not suggesting here that your team mindlessly follow a series of rules that are mandated in a top down approach. Developing a set of best practices/standards should be a collaborative process from the whole team where you discuss what approaches you want to take and pros and cons to different options. These standards also need to be a living document that grows, evolves, and is revisited both as your codebase grows and as the underlying technologies you’re using change.
Why Don’t Teams Codify Their Standards?
Given the costs of not having clear code standards as a team, why do so many engineering teams not have clearly articulated sets of best practices?
Initial time investment. It does take time to build up an initial set of standards you and your team agree on. But you can start small, with just a few standards you agree on and then build from there. Things like auto-formatters are great places to start, because they take out an entire class of inconsistency. And the long term time savings of establishing consistent approaches will outweigh the upfront time costs many times over.
Worrying about conflict. Sometimes different team members have very strong opinions about coding styles and best practice decisions. The risk of having these debates over best approaches can give some teams pause about discussing and establishing a set of best practices. But, settling these disagreements into an agreed upon general approach actually decreases conflict among your team in the long run because it cuts out having this discussion over and over again during code reviews.
Borrow, Steal, or Build from Scratch - It Doesn’t Matter
Thankfully you don’t have to build your entire set of code standards from scratch. There are a number of different types of style guides or best practice guides that different companies have published for different languages and frameworks. You can take these as a starting point and add or remove from them as you see fit. Here are a few popular ones:
You shouldn’t feel like you need to adopt everything within any external style guide that you’re looking to adopt - make sure you’re only choosing the standards that are relevant to your team. Here’s a look at how we implemented the Google Python Style Guide within Sourcery and where we agreed and disagreed with those styles.
Ideally you’ll then look to define rules that are more unique to your project. Types of guidelines you’ll typically look for here are things around naming standards, package and library dependencies (internal and external), and/or how to use internal libraries. These are typically the types of things that your team is already focused on during reviews and likely already has discussions about - it’s just about formalizing and codifying it.
Turning your best practices into code
Once you have your set of code standards you need to make sure all of your (new) code is following them. A common way to do this is to use a combination of linting tools for simple, formatting or style issues, along with manual code reviews for the broader standards. But, there’s a risk with any type of manual code review that issues will fall through the cracks - and it takes up more of your team’s limited time.
With Sourcery we’ve been working to make it easier and easier to turn your codified best practices into code - so that you can then automatically make sure those standards are followed throughout your development process. You can define any of your code standards as Sourcery rules and Sourcery will check for them while you’re writing new code in your IDE or be that first layer of code review in your CI. Or you can bring all your legacy code up to your standards by scanning it all with our CLI.