Dagger KSP

Note: Dagger’s KSP support is stable as of Dagger 2.60+ and KSP 2.3.9+.

Setup

Note: This guide focuses on Gradle. If you are using a different build system, please consult the documentation for that build system to enable KSP.

A general guide for migrating Gradle processors from KAPT to KSP can be found at https://developer.android.com/build/migrate-to-ksp.

The main steps are:

  1. Apply the KSP plugin.
  2. Change the compiler dependency configurations from kapt to ksp.
plugins {
  // STEP 1: Apply the KSP plugin (v2.3.9+)
  id "com.google.devtools.ksp" version "2.3.9"
}

// STEP 2: Change Dagger/Hilt compiler dependencies (v2.60+) to the ksp configuration.
dependencies {
  ksp "com.google.dagger:dagger-compiler:2.60.1" // Dagger compiler
  ksp "com.google.dagger:hilt-compiler:2.60.1"   // Hilt compiler
}

For additional build performance improvements, you can also try adding the experimental KSP flag, ksp.experimental.psi.resolution=true, to your gradle.properties file. This flag enables KSP’s experimental PSI resolution, which prefers a cheaper PSI-based resolution, and only falls back to more expensive symbol-based resolution via the Kotlin Analysis API when necessary (e.g. see https://github.com/google/ksp/issues/2816).

New Dagger SPI plugin (with KSP support)

Dagger’s KSP processor requires all registered Dagger SPI plugins to be converted to the new Dagger SPI plugin API. The new API provides wrappers around the Javac and KSP model types that allows users to write plugins that support both Javac and KSP. The full list of wrappers are shown below.

Dagger Wrapper Javac KSP
DaggerAnnotation AnnotationMirror KSAnnotation
DaggerType TypeMirror KSType
DaggerElement Element KSDeclaration
DaggerTypeElement TypeElement KSClassDeclaration
DaggerExecutableElement ExecutableElement KSFunctionDeclaration

Users can get access to the underlying Javac or KSP type of a wrapper by calling its #javac() or #ksp() methods, respectively. In addition, all wrappers have a #backend() method that can be used to switch logic based on the current backend. For example:

/** Returns the qualified name of the given {@link DaggerTypeElement}. */
String getQualifiedName(DaggerTypeElement typeElement) {
  switch (typeElement.backend()) {
    case JAVAC: return typeElement.javac().getQualifiedName();
    case KSP: return typeElement.ksp().getQualifiedName().asString();
    default: throw AssertionError("Unexpected backend: " + typeElement.backend());
  }
}

Note that calling #javac() when processing with KSP (or calling #ksp() when processing with Javac) will throw an exception.

Interaction with Javac/KAPT processors

KSP processors are not able to resolve types generated by other Javac/KAPT processors. Thus, if your project contains other processors that generate classes that need to interact with Dagger or Hilt, then those processors also need to be migrated to KSP.

For example, if you’re using the androidx.hilt:hilt-compiler, it should also be migrated to use the ksp configuration. KSP support for androidx.hilt:hilt-compiler is available in version 1.4.x.

Note that even if another processor is not directly related to Dagger/Hilt, it will still need to be migrated to KSP if its generated type needs to be inspected by the Dagger/Hilt processor. For example, consider the usage of an AutoFactory generated class within an @Inject-annotated constructor:

@AutoFactory
class SomeClass(@Provided val dep: Dep, arg: String)

class Foo @Inject constructor(val factory: SomeClassFactory)

If com.google.auto.factory:auto-factory:1.0.1 is in the kapt configuration, then the generated class SomeClassFactory will not be visible to the Dagger processor while it inspects the parameters of the @Inject constructor. For such cases, an error similar to the following will be raised:

... was unable to process ‘Foo’ because 'SomeClassFactory' could not be resolved.

Even though usages of @AutoFactory can be replaced with Dagger’s @AssistedInject APIs, there might be other processors that might prevent your project from migrating to KSP’s version of Dagger.