Effective handling your tech debt

 A simple guide to help you effectively handling the tech debt on your project.

As you may know, all the projects have some kind of tech debt. It’s normal, not a signal of bad developers. It’s also important to understand that even if you don’t touch your code for a while, your tech debt can increase. This can sound strange but constantly there are:

  • new ways to do things, some of them can be official recommendations of the platforms you use
  • external libraries are deprecated or upgraded

If you don’t have an effective process to handle this, your tech debt is going to grow to the infinite. Even if you have such a process, that’s not a guarantee of success. You need to follow it, define goals and reach them if you want to reduce your tech debt across time.

This guide is focused mainly on Java/Kotlin projects, but most of the tips can also work on other platforms too.

Kinds of tech debt

Let’s start defining some types of tech debt. These are just some examples. There are more, of course, and can vary according to the platform you use.

Library migrations

When you need to migrate from library A to library B.

There are multiple reasons to migrate. Library A could be abandoned, outdated or maybe you just found a better library.

Library upgrades

Having outdated libraries on your project could also be considered tech debt.

Sometimes upgrading can be as easy as incrementing the library version. But when the library breaks compatibility, the upgrade can be more difficult.

Part of this work can be automated but you always are going to need some manual work. You can read this article for more info:

Language migrations

Sometimes you need to migrate from one programming language to another. This is not usual but can happen.

Migrating your project from Java to Kotlin is an example of this.

External integrations migrations

When you need to migrate any external integration: an API, a dependencies repository, or any other integration.

Migrating from JCenter to Maven Central is an example of this.

Unused source code or resources

Also known as dead code. Having unused source code or resources on your project is bad for your build speed and developers' productivity. We can also consider this as tech debt.

This is a good plugin that can help you to find unused resources in your Android project:



When you find a better way to do the things in your source code.

Team Agreement

The first thing you should do is to have an agreement with the development team about what kind of things you consider as tech debt. You can’t have good progress fixing your tech debt if you don’t have an agreement about which is the tech debt of your project. The output of this step could be a well-defined list of tech debt items in your project.

This is an example of some common tech debt items you could have on a Java/Kotlin/Gradle/Android project:

  • Migrate from Groovy Gradle Scripts to Kotlin Gradle Scripts
  • Migrate from Jcenter to Maven Central
  • Migrate from Legacy Kotlin Parcelize to new Kotlin Parcelize plugin
  • Migrate from Kotlin Synthetic / Databinding to Jetpack view binding
  • Migrate from Java to Kotlin
  • Migrate to Coroutines

Document on a wiki

I recommend having a centralized wiki with all the agreed and pending tech migrations of your project. So, there is no doubt about how to implement new code. You don’t want to increase your tech debt just because a developer didn’t know that there is a better and agreed way to do some stuff.

This wiki should be your bible regarding tech debt. For each item, you could include links to official/internal documentation, migration tips, samples, metrics, reasons, etc.

Document your source code

Although the tech debt wiki is your bible, the source code is the first thing a developer is going to see. So, reflecting the tech debt in the source code is a great idea. Not always possible, but when possible, try to do it.

These are some ideas of how to do that on a Java/Kotlin project:


Add the @Deprecated annotation to all the source code that shouldn’t be used, because it is part of your tech debt.


Sometimes you can’t deprecate code or it doesn't make sense. Adding a //TODO or //FIXME comment can help other developers to understand what’s the recommended way to do certain things.

Use Legacy prefixes

If you have more than one way to do something, using the legacy word (as a package name or as a class/function prefix) can help developers to understand that the code is deprecated and there is another way to do that.

Measure your progress

Measuring your progress regarding the pending tech debt is fundamental if you want to succeed.

For each item on your tech debt wiki, just measure the number of occurrences in your code. In most cases, you can do that by counting imports or certain words in your code.

For example, suppose you defined Migrate from Kotlin Synthetic to Jetpack view binding as a tech debt, then you could measure your progress with a bash script that counts the number of kotlinx.android.synthetic imports on your code.

usages=`grep -r . -e "import kotlinx.android.synthetic.*$" --include=\*.{java,kt} | wc -l | xargs echo`
# TODO Track the usages variable to your tool of choice (Grafana, InfluxDB, Datadog, etc)

You could run that script on your continuous integration tool, every time someone pushes to the default branch.

You are going to need a tool where you can store and graph your measures. Grafana is an interesting tool you can use to graph your tech debt, it can connect to multiple data providers.

Assign goals

Once you started measuring your tech debt, you can easily assign goals and understand how close are you to completing them.

Using the previous example, if you are measuring Migrate from Kotlin Synthetic to Jetpack view binding as a tech debt, and you detected 500 imports, then you could assign a goal to fix for example at least100 imports per week.

Fix your tech debt

You need to assign time to fix your tech debt and reach your goal. I know, it's no easy when you have lots of business features to implement, but the code quality pays. You can read more about this topic in this Martin Fowler article:

Once you fixed a tech debt item, you want to prevent other developers from repeating the same error, increasing your tech debt again. Try to close each tech debt item as soon as possible, avoiding tackling too much different tech debt items at the same time. So, you have more chances to prevent other devs from doing things in the wrong way. For example, if you migrated your code from library A to library B, removing library A dependency declarations will prevent any other developer from using it. If you are on an Android project, you can create your custom lint rules, and make the build fail when someone does things in the wrong way. You can also have bash scripts or Gradle tasks to validate your code, verifying that no new tech debt is introduced in the code.

You can follow Dipien on Twitter for productivity tools & ideas for Android, Kotlin & Gradle projects.

This article contains Affiliate Links. If you purchase anything after clicking an affiliate link, I may receive some compensation.

If you want to learn Android, here you have some recommended books


Popular Posts

Versioning Android apps

Circle CI + Android configuration tips

Say bye-bye to Android Jetifier