Migrate from Kapt to KSP, Kapt will be deprecated soon.

I will show you how to migrate from Kapt plugin to KSP plugin in android project.

Kaushal Vasava
5 min readAug 19, 2023
It is Kapt to KSP migration image.

What is Kapt?

Kapt (the Kotlin Annotation Processing Tool) allows you to use Java annotation processors with Kotlin code, even if those processors don’t have specific support for Kotlin. This is done by generating Java stubs from your Kotlin files that the processors can then read. This stub generation is an expensive operation and has a significant impact on build speed.

Kapt is now in maintenance mode, and we recommend migrating from kapt to KSP wherever possible. In most cases, this migration only requires changes to your project’s build configuration.

Why we use Kapt?

Some usage of kapt:

  • Annotation processor arguments

Use arguments {} block to pass arguments to annotation processors:

kapt {
arguments {
arg("key", "value")
}
}
  • Gradle build cache support

The kapt annotation processing tasks are cached in Gradle by default. However, annotation processors run arbitrary code that may not necessarily transform the task inputs into the outputs, might access and modify the files that are not tracked by Gradle etc. If the annotation processors used in the build cannot be properly cached, it is possible to disable caching for kapt entirely by adding the following lines to the build script, in order to avoid false-positive cache hits for the kapt tasks:

kapt { useBuildCache = false }

  • Work Kapt as annotation processor

We use for Room like this.

implementation "androidx.room:room-ktx:2.5.2"
kapt("androidx.room:room-compiler:2.5.2")

We use for Dagger-hilt like this.

implementation "com.google.dagger:hilt-android:2.44.2"
kapt "com.google.dagger:hilt-android-compiler:2.44.2"
kapt "androidx.hilt:hilt-compiler:1.0.0"

What is KSP?

KSP (Kotlin Symbol Processing) is a Kotlin-first alternative to kapt. KSP analyzes Kotlin code directly, which is up to 2x faster. It also has a better understanding of Kotlin’s language constructs.

You can run kapt and KSP alongside each other in your project while you’re migrating, and the migration can be done module by module, library by library.

Note: If a module has any kapt processors remaining, stubs are still generated in that module. This means that the majority of performance improvement will occur only when all usages of kapt are removed from the module.

Why is KSP faster?

The Kotlin Annotation Processing Tool (KAPT) works with Java’s annotation processing infrastructure to make most Java language annotation processors work in Kotlin out of the box. To do this, KAPT compiles Kotlin code into Java stubs that retain information that Java annotation processors care about. Creating these stubs is costly though and means the compiler must resolve all the symbols in your program multiple times (once to generate stubs, and then again to do the actual compilation).

KSP moves away from the stub generation model by working as a Kotlin compiler plugin — it allows annotation processors to read and analyze source programs and resources directly in Kotlin instead of requiring you to depend on the Java annotation processing infrastructure. This both dramatically improves build speed (up to 2x faster for Room’s Kotlin test app) and means that KSP can be used for non-Android and non-JVM environments like Kotlin/Native and Kotlin/JS.

Usage is same as Kapt.

Migration steps:

Here’s an overview of the migration steps:

  1. Check the libraries you use for KSP support.
  2. Add the KSP plugin to your project.
  3. Replace annotation processors with KSP.
  4. Remove the kapt plugin.

1. Check the libraries you use for KSP support

To get started, check if the libraries you’re using with kapt already have KSP support. This is the case for many popular libraries (including Glide, Room, and Moshi), and others (such as Dagger) are adding support.

You can check the list of supported libraries in the documentation, or refer to the documentation and issue tracker of the libraries you’re using.

Note: While not a traditionally-included library dependency, Data Binding also uses an annotation processor to provide its functionality, and KSP support for Data Binding is not planned. You can mitigate the impact of kapt on your build by isolating the usages of Data Binding to separate modules.

2. Add the KSP plugin to your project

First, declare the KSP plugin in your top level build.gradle.kts file. Make sure that you choose a KSP version aligned with your project's Kotlin version. You can find a list of releases on the KSP GitHub page.

plugins {
id("com.google.devtools.ksp") version "1.8.22-1.0.11" apply false
}

Then, enable KSP in your module-level build.gradle.kts file:

plugins {
id("com.google.devtools.ksp")
}

3. Replace annotation processors with KSP

With KSP enabled, you can start replacing usages of kapt with KSP. For a vast majority of libraries, this just requires changing kapt to ksp at the dependency declaration, as they ship their annotation processor and KSP processor in the same artifact.

Note: Some libraries (such as Glide) might require you to change the dependency to a different artifact as well. Make sure to consult their documentation.

dependencies {
kapt("androidx.room:room-compiler:2.5.2") // remove this dependency
ksp("androidx.room:room-compiler:2.5.2") // add this dependency
}

After moving to KSP, sync and build your project to see if it still works correctly.

Some common issues to look out for:

  • Some libraries don’t support the exact same set of features with kapt and KSP. If your code breaks after migrating, check the library’s documentation.
  • KSP has more accurate Kotlin type information than kapt (for example, about nullability), which means that KSP processors can be more precise about type requirements. This might require some fixes in your source code as well, in addition to updating your build files.
  • If you were previously passing in arguments to the annotation processor, you’ll likely need to pass in those arguments to KSP now. Note that the format of the arguments might differ between kapt and KSP. See the KSP documentation and consult the documentation of the library you’re using to learn more.

4. Remove the kapt plugin

When you have no dependencies included with kapt in your module anymore, remove the kapt plugin.

Note: Data Binding also requires kapt to be enabled in the module. In modules where Data Binding is used, kapt can not be removed.

If it was declared in a plugins block:

plugins {
id("org.jetbrains.kotlin.kapt")
}

If it was using the apply plugin syntax using Groovy:

apply plugin: 'kotlin-kapt'

You should also remove any leftover configuration related to kapt, such as:

kapt {
correctErrorTypes = true
useBuildCache = true
}

Thank you for reading this article! Don’t forget to clap only if you think I deserve it👏

If you have any query related to Android, I’m always happy to help you. You can reach me on LinkedIn, Twitter , Github and Instagram.

Happy Learning🚀 Happy Coding💻

--

--

Kaushal Vasava

Android Developer | Kotlin | Jetpack Compose | Kotlin MultiPlatform | LinkedIn's Top Voice (3K+ Followers) | Apps with 100K+ Downloads on the Playstore