KSP & Annotation Processing

Kotlin Symbol Processing (KSP) is the modern way to generate code at compile time from annotations — the engine behind Room, Hilt, and Moshi — replacing the slower, Java-stub-based KAPT.

Learn KSP & Annotation Processing in our free Kotlin course — a beginner-friendly interactive lesson with worked examples, a practice exercise and a quick…

Part of the free Kotlin course at LearnCodingFast — hands-on lessons with examples you run in your browser, plus practice exercises and a quick quiz.

By the end you'll understand how KSP works, how it differs from KAPT, and how a SymbolProcessor generates sources.

What You'll Learn in This Lesson

1️⃣ What Compile-Time Code Generation Is

You add an annotation; a processor reads it during compilation and writes new Kotlin source. The generated code is compiled with yours — no runtime reflection, full type safety.

This is exactly how Room turns a @Dao interface into a working implementation behind the scenes.

2️⃣ Wiring KSP in Gradle

Apply the KSP plugin, then register each processor with the ksp(...) configuration — the faster, Kotlin-native replacement for kapt(...) .

KSP understands Kotlin directly instead of generating Java stubs, which is why it builds significantly faster than KAPT.

3️⃣ Inside a SymbolProcessor

A SymbolProcessorProvider is the entry point that creates your SymbolProcessor . Its process() method uses a Resolver to find annotated symbols and a CodeGenerator to emit files.

Write a provider and processor that finds annotated symbols and logs how many it found.

📋 Quick Reference — KSP

Practice quiz

What does KSP stand for?

  • Kotlin Symbol Processing
  • Kotlin Standard Plugin
  • Kotlin Source Packager
  • Kotlin Static Profiler

Answer: Kotlin Symbol Processing. KSP is Kotlin Symbol Processing, an API for building lightweight compiler plugins that read code and generate new sources.

When does KSP run relative to your program?

  • Only when the app is installed
  • During code review
  • At compile time, generating code before/while the code compiles
  • At runtime, on every launch

Answer: At compile time, generating code before/while the code compiles. KSP is a compile-time tool: it inspects symbols and generates additional source files that are then compiled with your code.

What is the main advantage of KSP over KAPT?

  • It runs your app faster at runtime
  • It is faster because it understands Kotlin natively instead of generating Java stubs
  • It needs no annotations at all
  • It replaces Gradle

Answer: It is faster because it understands Kotlin natively instead of generating Java stubs. KAPT generates Java stubs for the Java annotation processing API, which is slow; KSP reads Kotlin directly, making builds significantly faster.

Which Gradle configuration adds a KSP processor to a module?

  • annotationProcessor(...)
  • implementation(...)
  • kapt(...)
  • ksp(...)

Answer: ksp(...). You declare a symbol processor with the ksp(...) configuration in your dependencies block, after applying the KSP Gradle plugin.

Which interface do you implement to define a KSP processor?

  • SymbolProcessor
  • KspPlugin
  • CodeGenerator
  • AnnotationProcessor

Answer: SymbolProcessor. A processor implements SymbolProcessor; its process() method inspects resolved symbols and emits generated code.

What is the role of SymbolProcessorProvider?

  • It signs the APK
  • It is a factory that creates your SymbolProcessor instance
  • It runs the app
  • It downloads dependencies

Answer: It is a factory that creates your SymbolProcessor instance. SymbolProcessorProvider is the entry point KSP discovers; its create() method returns your SymbolProcessor.

Why does KSP generate code at build time rather than using runtime reflection?

  • It does not; KSP uses reflection
  • To make the APK larger
  • Because reflection is unavailable in Kotlin
  • For better performance and compile-time safety, avoiding slow runtime reflection

Answer: For better performance and compile-time safety, avoiding slow runtime reflection. Generating code at compile time avoids the runtime cost and unpredictability of reflection and surfaces errors during the build.

Which of these libraries commonly uses KSP for code generation?

  • The Android emulator
  • OkHttp only
  • Room, Hilt, and Moshi
  • The Kotlin standard library

Answer: Room, Hilt, and Moshi. Room (DAOs), Hilt/Dagger (the dependency graph), and Moshi (JSON adapters) all generate code via annotation processing, with KSP support.

Where does KSP place the sources it generates?

  • In the system temp folder only
  • In a generated build directory that is compiled alongside your code
  • Inside your src/main folder
  • In the Android manifest

Answer: In a generated build directory that is compiled alongside your code. Generated files land in a build/generated output directory and are added to the compilation, so you can reference them like normal code.

Compared with writing the boilerplate by hand, what does annotation processing give you?

  • Generated, consistent boilerplate from annotations, reducing manual errors
  • A different programming language
  • Automatic UI design
  • Slower compilation with no benefit

Answer: Generated, consistent boilerplate from annotations, reducing manual errors. Annotation processors generate repetitive code from your annotations, keeping it consistent and freeing you from writing it by hand.