Technical debt is a common term in software engineering management. It has been the target of debates for many years. The name comes from a financial analogy because some people defend that developers buy time by shipping faster (and with lower-than-expected quality).
At some point, developers must pay back this time by refactoring, rewriting, or fixing existing code instead of adding more value to the business.
There is another line of thought. It says technical debt is a sacrifice of maintainability in favor of other requirements. This definition sounds better because it fits for the three significant kinds of technical debt:
- Planned Technical Debt, which is that debt intentionally created to achieve a given requirement. Sometimes it’s time to market, but there are other possibilities. For instance, your team may decide to ship code with the presence of code smells, because there’s a discussion going on that would impact in that piece of code. Later, with a decision on hands, the team then pays the debt properly.
- Unintentional Technical Debt occurs when developers are not aware of the defects they create. Common reasons include lack of knowledge, communication, or attention.
- Unavoidable Technical Debt occurs due to deprecation of existing code due to business or technology changes and evolution. If you add an external library to your project, you need to keep it updated in other to pay an unavoidable debt. Otherwise, security breaches may pop up, performance may slow down, and other issues may come up.
Preventing technical debt with linters
Linters are tools that perform static code analysis. They usually look for Code Smells, Code Complexity, Potential bugs, Security Issues, and Styleguide nonconformities.
Those kinds of problems are likely to happen to any developer in any company. So, the first thing to do is to make sure they get visible before the code is shipped.
1. Running linters before pushing code
Some developers are used to run linters through their development flow. Linters tell them the found issues, and then they fix before committing or pushing. It’s a simple practice that prevents technical debts.
As feedback is fast, fixing any issue is also fast. But, relying only upon this practice does not guarantee visibility nor promotes healthy discussions among team members.
2. Running linters during code review
This practice has become very popular lately. It consists of running linters for every pull request opened. The author should include found issues in the pull request, so the team gains visibility on the introduced technical debts.
Code review is the best occasion to discuss someone’s implementation. It is also a great place to uncover and plan technical debts gathering the team’s attention. The team can make the decision together, which counts a lot later when the time to payoff arrives.
Some tools, like SourceLevel, add found issues as comments in the proper line of code. It promotes focused discussions and makes the fix easier.
3. Standardizing style guides and configurations
When a team decides to create a style guide to define their preferences and conventions for code formatting, every developer should follow them. As time goes, the number of repositories grows. Linters configuration files are copied over and over to each one of them. Soon, it gets messy: their content diverges, and config files get outdated.
To solve this problem, it is a best practice to create a single repository containing all the linters configuration files in it. Those are the official assets for any new or existing project.
This solution is great because it allows developers to take advantage of pull requests to discuss the status quo and keep the history of the conversation that accepted or declined the proposed changes.
If you use SourceLevel as your automated code review, instead of copying and pasting files, you can configure a single file and point to this specific repository. It does easy the process of keeping all repositories’ code consistent, therefore avoiding technical debt.
Reducing technical debt with linters
Assuming your team is already preventing unintentional technical debts to reach your master branch, you’re ready to start working on the existing ones. To do so, I strongly recommend you and your team to choose a code quality improvement strategy.
1. Measuring technical debt
You need to ensure nobody is working with guts or intuition. Team members can’t feel the improvement; they need actually to see it. The best way to visualize improvement is through metrics and charts. Actual numbers tell the story.
You need to run the linters on a daily or weekly basis, collect the information provided, and store in a Spreadsheet the number of issues found in each category provided by the engine. Plotting a chart is easy. That’s what SourceLevel does in an automated way.
2. Centering all the issues in a single place
Supposing you got the numbers, now you need to give visibility of the issues and make a plan. You and your team should work towards the reduction of technical debts.
Centering all the issues in a single place avoids rework. It also gives a sense of progress when the number of issues drops over time. It motivates the team and organizes the work.
SourceLevel displays all found issues in a single. Users can easily filter by engine’s categories or languages. You can manually do a similar job by creating cards in Trello, Jira, Clubhouse or even in a Spreadsheet. It’s crucial, though, to keep it up to date. Otherwise, the team starts neglecting the practice. Soon, technical debts increase again.
3. Institutionalization of technical debt control
It’s unlikely to zero the number of technical debts in any project. Modern business, massive team rotation due to high turnover, and the fast pace of technology’s evolution make it hard to catch it up.
Institutionalizing a strategy to pay off technical debts is vital. When your team sees it as part of their workflow, the chances to keep the numbers under control rises. My suggestion is to bring team members to the discussion, listen to their input, expose your concerns. That’s the way to make it part of the culture.
Linters are fundamental to bring visibility of technical debts. They can help to prevent and reduce the three kinds: planned, unintentional, and unavoidable debts.
I presented 3 practices to prevent technical debt. They are running linters before pushing code, running linters during code review, and standardizing style guides and configurations. Also, I listed 3 practices to reduce them: measuring technical debt, centering all the issues in a single place, and institutionalization of technical debt control.
SourceLevel is changing directions!
After October 1st, 2021, we will focus all our efforts on our (All-in-one) Analytics & Data Platform for Engineering Teams, thus we’re discontinuing the Automated Code Review feature.