Kotlin Support

Moshi provides first-class support for Kotlin, making it an excellent choice for modern Android and server-side applications. It understands Kotlin's language features like non-nullable types and default parameter values. There are two primary ways to use Moshi with Kotlin: reflection and code generation.

Option 1: Kotlin Reflection

The reflection-based adapter is the easiest way to get started. It uses the kotlin-reflect library at runtime to inspect your classes and determine how to serialize and deserialize them.

Setup

Add the moshi-kotlin dependency to your project:

// build.gradle.kts
implementation("com.squareup.moshi:moshi-kotlin:1.15.2")

This artifact has a transitive dependency on org.jetbrains.kotlin:kotlin-reflect, which is a ~2.5 MB library.

Usage

To enable reflection, add the KotlinJsonAdapterFactory to your Moshi.Builder. It's recommended to add it with addLast() so that your custom adapters have precedence.

import com.squareup.moshi.Moshi
import com.squareup.moshi.kotlin.reflect.KotlinJsonAdapterFactory

val moshi = Moshi.Builder()
    // ... add any custom adapters first
    .addLast(KotlinJsonAdapterFactory())
    .build()

With this setup, Moshi can now serialize and deserialize your Kotlin data classes out of the box.

Pros & Cons

  • Pros: Simple to set up, no build plugins or annotation processing required.
  • Cons: Adds the kotlin-reflect dependency to your project, which may increase your app's size. It is also slower than code generation due to the overhead of runtime reflection.

Option 2: Kotlin Codegen (KSP)

For better performance and a smaller runtime footprint, Moshi offers a code generation module that uses the Kotlin Symbol Processing (KSP) API. It generates efficient, handwritten-style JsonAdapters for your classes at compile time.

Setup

  1. Apply the KSP plugin to your Gradle build file:

    // build.gradle.kts
    plugins {
      id("com.google.devtools.ksp") version "1.8.21-1.0.11" // Or latest KSP version
    }
  2. Add the moshi-kotlin-codegen dependency to your ksp configuration:

    dependencies {
      ksp("com.squareup.moshi:moshi-kotlin-codegen:1.15.2")
    }

Usage

Annotate your Kotlin data classes with @JsonClass(generateAdapter = true).

import com.squareup.moshi.JsonClass

@JsonClass(generateAdapter = true)
data class Player(val name: String, val score: Int)

When you build your project, KSP will generate a PlayerJsonAdapter class. Moshi will automatically find and use this generated adapter. Your Moshi instance setup can be minimal:

val moshi = Moshi.Builder().build()

Pros & Cons

  • Pros: Excellent performance, no runtime reflection, and does not require the kotlin-reflect library. Generates R8/ProGuard rules automatically.
  • Cons: Requires an initial build configuration step and relies on a compile-time process.

Mixing Reflection and Codegen

You can use both approaches in the same project. If you include KotlinJsonAdapterFactory and also annotate some classes with @JsonClass(generateAdapter = true), Moshi will prioritize the generated adapter for the annotated classes and fall back to reflection for the others. This can be a useful strategy for optimizing critical paths while maintaining convenience for less performance-sensitive models.