You're reading for free via SUMIT KUMAR's Friend Link. Become a member to access the best of Medium.
Member-only story
KSP vs KAPT — What is the difference between KSP and KAPT with their use-case.
Modern Kotlin development often involves generating boilerplate code, especially when working with libraries like Room, Dagger, or Moshi. Two primary tools for code generation in Kotlin are KSP (Kotlin Symbol Processing) and KAPT (Kotlin Annotation Processing Tool). While both serve similar purposes, they operate differently and have distinct use cases. This article explores their differences, use cases, and the internal workings of code generation with real-life examples.
A book can be written on this topic only, however in this article we will focus on their definition and differences rather than going into compilation and generation level base(may be some other day).

If you are not a medium paid member user then use friend link to access the article without any paywall : )
Real-Life Analogy: Blueprint vs. Translator
- KAPT (Translator Approach): Imagine translating a complex blueprint from one language to another before processing it. The translation step (Java stubs) slows down the process and can lose details.
- KSP (Direct Approach): Now imagine giving the blueprint directly to a native speaker. They can work faster and with greater accuracy (Kotlin-first processing).
Now, lets explore things more technically and in detail.
What is KAPT?
KAPT (Kotlin Annotation Processing Tool) is the older tool for annotation processing in Kotlin projects. It was created to make Java-based annotation processors work with Kotlin code by generating Java stubs(nothing but simplified Java code from kotlin).
Kotlin code — → Java Stub — → libraries uses these stubs — → generate required classes.
How KAPT Works (Internal Functioning)
- Kotlin Code Compilation: Kotlin code is compiled into Java stubs.
- Java Stubs Generation: These stubs are simplified Java code representations of the Kotlin code, enabling Java annotation processors to work with them.
- Annotation Processing: Java annotation processors like Dagger analyze the generated stubs and generate additional Java code.
- Code Integration: The generated code is then compiled and linked back with the original Kotlin code.
Example Use Case:
Imagine using Dagger for dependency injection in a Kotlin project:
@Module
class AppModule {
@Provides
fun provideRepository(): Repository = RepositoryImpl()
}
KAPT generates Java stubs like:
public final class AppModule {
public Repository provideRepository() {
return new RepositoryImpl();
}
}
Dagger processes these stubs to generate the required dependency injection code. So if using KAPT, first java stubs are created for your kotlin code and then libraries(dagger,room,etc.) uses those stubs to generate the required classes, eg: for `AppModule.kt` class first AppModule.java
(java stub) is created and then dagger generate AppModule_impl.java
Downsides of KAPT:
- Slower Build Times: The stub generation step adds overhead.
- Limited Kotlin Feature Support: Kotlin-specific features like
suspend
functions andinline
classes aren't fully supported. - Error-Prone: Errors may arise from mismatched Kotlin and Java constructs.
What is KSP?
KSP (Kotlin Symbol Processing) is a modern, Kotlin-native tool designed to replace KAPT for faster and more efficient code generation. KSP interacts directly with Kotlin code without needing Java stubs.
Kotlin Code → Kotlin Symbol Processor (Direct Parsing) → Annotation Processor Library(dagger/room,etc.) → Generated Classes.
How KSP Works (Internal Functioning)
- Direct Kotlin Code Analysis: KSP works directly with the Kotlin compiler frontend.
- Symbol Analysis: It processes the Kotlin Abstract Syntax Tree (AST) and Kotlin-specific symbols.
- Code Generation: Generates Kotlin code directly, skipping the need for Java stubs.
Example Use Case:
Using Room for database access:
@Entity
data class User(
@PrimaryKey val id: Int,
val name: String
)
With KSP, the Room library directly generates the required DAO implementations and SQL queries based on Kotlin symbols, skipping the stub generation step entirely.
Advantages of KSP:
- Faster Build Times: No stub generation reduces overhead.
- Better Kotlin Feature Support: Works directly with Kotlin-specific features like
suspend
functions. - Simpler Architecture: Direct integration with the Kotlin compiler.
Key Differences Between KSP and KAPT

When to Use KSP vs KAPT (Real-Life Examples)
Use KSP When:
- Working with modern Kotlin libraries that support KSP.
- Example: You’re using Room for database operations in a Kotlin project. Room has native KSP support, which is faster and more efficient than KAPT.
- Why KSP? It integrates seamlessly with Kotlin and reduces build times.
2. Writing custom Kotlin code generators.
- Example: You’re building a library that generates Kotlin-specific boilerplate code, such as data classes or extension functions, based on annotations.
- Why KSP? It provides direct access to Kotlin’s syntax and type system, making it easier to generate Kotlin code.
3. Optimizing build performance.
- Example: Your project uses Moshi for JSON serialization, and switching from KAPT to KSP reduces annotation processing overhead, speeding up builds.
- Why KSP? It avoids the inefficiencies of Java-based annotation processing.
Use KAPT When:
- Using Java annotation processors that don’t support KSP.
- Example: You’re using Glide for image loading, which relies on Java-based annotation processing and doesn’t have KSP support.
- Why KAPT? It’s the only option for Java-only annotation processors.
2. Migrating a legacy Java project to Kotlin.
- Example: Your project uses Dagger 2 for dependency injection, and you’re gradually converting the codebase to Kotlin. Dagger 2 doesn’t fully support KSP yet.
- Why KAPT? It ensures compatibility with existing Java-based tools during migration.
3. Working with Java-only tools or libraries.
- Example: You’re using AutoValue to generate immutable value classes, which is a Java-based library.
- Why KAPT? Java-only libraries require the traditional annotation processing framework.
When Not to Use KSP or KAPT:
- If the library doesn’t require annotation processing.
- Example: You’re using Kotlinx.serialization for JSON parsing. It doesn’t rely on annotation processing, so neither KSP nor KAPT is needed.
- Why avoid? It’s unnecessary, as the library works natively with Kotlin.
2. If you’re building a pure Kotlin project without annotation-based libraries.
- Example: Your project doesn’t use libraries like Room, Dagger, or Moshi, and you don’t need code generation.
- Why avoid? KSP and KAPT add complexity and overhead when not required.
3. If you’re prioritizing simplicity in small projects.
- Example: For a small app, using libraries that don’t require annotation processing (e.g., manual dependency injection or simple JSON parsing) can simplify the build process.
- Why avoid? Annotation processing tools can slow down builds unnecessarily in small-scale projects.
Thank you for reading! I hope you enjoyed the article and found it valuable in enhancing your knowledge. Stay tuned for high-quality articles that will further enrich your understanding. If you have any further questions or would like to contribute to the discussion, please feel free to leave your comments below. Your feedback and engagement are greatly appreciated. Thank you once again, and happy coding!