Skip to content

Kotlin Symbol Processing (KSP)

Kotlin Symbol Processing is a tool that allows feeding Kotlin source code to processors, which can in turn use this information to generate code, classes, or resources, for instance. Amper provides built-in support for KSP.

Some popular libraries also include a KSP processor to enhance their capabilities, such as Room or Moshi.

Info

Amper works with KSP2, so any processors used must be compatible with KSP2. We’re expecting most processors to make this upgrade soon, as KSP1 is no longer part of KSP releases. However, at the moment, you might still see some gaps in support, such as issues with native targets.

To add KSP processors to your module, add their maven coordinates to the settings.kotlin.ksp.processors list:

module.yaml
settings:
  kotlin:
    ksp:
      processors:
        - androidx.room:room-compiler:2.7.0-alpha12

Multiplatform support

In multiplatform modules, all settings from the settings section apply to all platforms by default, including KSP processors. If you only want to add KSP processors for a specific platform, use a settings block with a @platform qualifier:

module.yaml
# the Room processor will only process code that compiles to the Android platform
settings@android:
  kotlin:
    ksp:
      processors:
        - androidx.room:room-compiler:2.7.0-alpha12

Generated code is not available in common sources

In multiplatform modules, KSP is called for each platform separately. This means that any code generated by KSP processors will be available only for the corresponding platform. There is no way at the moment to access the generated code from the common fragment (src) or intermediate fragments (e.g. src@native).

This limitation comes from the Kotlin compilation model and how KSP aligns with it. Please follow the relevant KSP issue for more information.

Passing options to KSP processors

Some processors can be customized by passing options. You can pass these options using the processorOptions section:

settings:
  kotlin:
    ksp:
      processors:
        - androidx.room:room-compiler:2.7.0-alpha12
      processorOptions:
        room.schemaLocation: ./schema

Consult the documentation of the processor you want to use for more information about the available options.

Note

Note: all options are passed to all processors by KSP. It's the processor's responsibility to use unique option names to avoid clashes with other processor options.

Using your own local KSP processor

You can implement your own processor in an Amper module as a regular JVM library, and then use it to process code from other modules in your project.

Usually, 3 modules are involved:

  • The processor module, with the actual processor implementation
  • The annotations module (optional), which contains annotations that the processor looks for in the consumer code
  • The consumer module, which uses KSP with the custom processor

The annotations module is a very simple JVM library module without any required dependencies (it's just here to provide some annotations to work with, if necessary):

my-processor-annotations/module.yaml
product:
  type: lib
  platforms: [ jvm ]

The processor module is a JVM library with a compile-only dependency on KSP facilities, and on the custom annotations module:

my-processor/module.yaml
product:
  type: lib
  platforms: [ jvm ]

dependencies:
  - ../my-processor-annotations
  - com.google.devtools.ksp:symbol-processing-api:2.0.21-1.0.25: compile-only

The consumer module adds a regular dependency on the annotations module, and a reference to the processor module:

my-consumer/module.yaml
product: jvm/app

dependencies:
  - ../my-processor-annotations # to be able to annotate the consumer code

settings:
  kotlin:
    ksp:
      processors:
        - ../my-processor # path to the module implementing the KSP processor

For more information about how to write your own processor, check out the KSP documentation.