Need help with your JSON?
Try our JSON Formatter tool to automatically identify and fix syntax errors in your JSON. JSON Formatter tool
Kotlin JSON Serialization and Formatting Libraries
If you are choosing a Kotlin JSON library today, the short answer is simple: use kotlinx.serialization for most new Kotlin projects, especially if you care about Kotlin Multiplatform, compiler-checked models, or minimal runtime reflection. Use Jackson when you are already in a Jackson-centric JVM stack, and keep Moshi when an existing Android or JVM app already depends on it. Gson is still common in older codebases, but it is no longer the first recommendation for new Kotlin-first work.
Search visitors usually need two slightly different things here: a library for mapping JSON to Kotlin data classes, and a practical way to format or pretty-print JSON. The best libraries do both, but their tradeoffs are different. This guide focuses on that decision first, then shows the modern Kotlin setup that people actually use.
Quick Recommendation
- New Kotlin or Kotlin Multiplatform project: choose
kotlinx.serialization. - Spring Boot or an existing Jackson backend: stay with
jackson-module-kotlinunless you have a clear reason to standardize on something else. - Existing Android app already using Moshi adapters: Moshi is still a solid choice.
- Legacy app already built around Gson: keep it if the codebase is stable, but do not pick it first for a new Kotlin project.
Which Library Fits Which Job?
| Library | Best for | Strengths | Watch out for |
|---|---|---|---|
kotlinx.serialization | New Kotlin apps, KMP, shared models, low-reflection setups | Official Kotlin library, compiler plugin, strong Kotlin type support, easy pretty printing | Requires the serialization plugin and explicit serializers for some advanced cases |
jackson-module-kotlin | JVM services, Spring Boot apps, mixed Java and Kotlin stacks | Huge ecosystem, common server-side default, integrates well with existing Jackson tooling | JVM-only and heavier than Kotlin-first alternatives if all you need is Kotlin model mapping |
| Moshi | Existing Android or JVM apps already built around Moshi | Clean adapter API, Kotlin-aware codegen, familiar in many Android codebases | Not multiplatform, and Kotlin support is best when you use codegen or the Kotlin adapter factory |
| Gson | Legacy maintenance and Java interoperability | Ubiquitous, familiar, and easy to find in older tutorials | Less natural Kotlin handling around nullability, defaults, and modern Kotlin-first conventions |
Why kotlinx.serialization Is the Default Pick
JetBrains maintains kotlinx.serialization as the official Kotlin serialization library, and that matters in practice. It works across JVM, Android, JavaScript, Native, and iOS targets, fits naturally with Kotlin data classes and sealed hierarchies, and avoids the "Java library with Kotlin add-ons" feeling that you get from older options.
It is also a good fit for formatting JSON, not just data binding. If you need a compact API payload in one place and human-readable pretty JSON in another, you can do both with the same library and the same model types.
Setup
The important rule is that the Kotlin serialization compiler plugin should match your Kotlin version. The JSON runtime library has its own version, so check the latest compatible release when you add it.
build.gradle.kts
plugins {
kotlin("jvm") version "<your-kotlin-version>"
kotlin("plugin.serialization") version "<same-kotlin-version>"
}
repositories {
mavenCentral()
}
dependencies {
implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:<latest-compatible-version>")
}If serialization mysteriously fails at compile time, the missing plugin is usually the reason. Adding the runtime dependency alone is not enough.
Basic Serialization and Deserialization
For normal application code, the pattern is simple: annotate the model with @Serializable, create a configured Json instance, and then encode or decode.
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable
import kotlinx.serialization.encodeToString
import kotlinx.serialization.decodeFromString
import kotlinx.serialization.json.Json
@Serializable
data class ApiUser(
@SerialName("user_id") val id: String,
val name: String,
val roles: List<String> = emptyList(),
val email: String? = null
)
val json = Json {
ignoreUnknownKeys = true
encodeDefaults = true
}
fun main() {
val input = """{"user_id":"42","name":"Ada","extra":"ignored"}"""
val user = json.decodeFromString<ApiUser>(input)
println(user) // ApiUser(id=42, name=Ada, roles=[], email=null)
println(json.encodeToString(user))
// {"user_id":"42","name":"Ada","roles":[],"email":null}
}Two small configuration flags do a lot of work here. ignoreUnknownKeys = true keeps your app from breaking when an API adds fields you do not care about yet, and encodeDefaults = true makes default-valued properties show up in output when you want stable, explicit JSON.
Formatting and Pretty Printing JSON
If your goal is formatting rather than object mapping, parse the raw JSON into a JsonElement and then write it back out with prettyPrint enabled. That gives you a clean formatter without creating data classes.
import kotlinx.serialization.encodeToString
import kotlinx.serialization.json.Json
import kotlinx.serialization.json.JsonElement
import kotlinx.serialization.json.parseToJsonElement
fun main() {
val raw = """{"name":"Ada","languages":["Kotlin","Swift"],"active":true}"""
val formatter = Json {
prettyPrint = true
prettyPrintIndent = " "
}
val element = Json.parseToJsonElement(raw)
val formatted = formatter.encodeToString(JsonElement.serializer(), element)
println(formatted)
}That is the practical answer when someone says "I just need Kotlin JSON formatting." If you only want to validate and reformat arbitrary JSON text, you do not need to model the payload first.
Common Kotlin JSON Gotchas
- Default values affect missing fields. A property with a default can be omitted in incoming JSON; a non-default property is required.
- Unknown fields are strict by default. If your API evolves often, set
ignoreUnknownKeys = trueor use@JsonIgnoreUnknownKeyson specific models. - Pretty printing is output-only.
prettyPrintchanges how JSON is written, not how it is parsed. - Lenient mode is not a free win.
isLenient = trueaccepts non-standard JSON, which can hide bad upstream data. Use it only when you control the format and truly need it. - Polymorphism needs planning. Sealed classes and custom serializers are well supported, but you should decide early how type discriminators should appear in JSON.
When Jackson or Moshi Is the Better Answer
Jackson is still a very reasonable choice for Kotlin on the JVM, especially on backend teams already using Jackson modules, annotations, and tooling. That is common in Spring Boot applications, where the default JSON stack is already built around Jackson. If your whole service ecosystem speaks Jackson, changing libraries just for Kotlin syntax is usually not worth the churn.
Moshi remains a good option for existing Android and JVM apps. Its adapter model is clean and flexible, and the current Moshi guidance is to use Kotlin code generation or KotlinJsonAdapterFactory when you want Kotlin-aware behavior. If your codebase already has Moshi adapters and tests, staying there can be the pragmatic choice.
Gson is best treated as a compatibility choice. It still works, and many production systems still use it, but new Kotlin-focused projects are usually better served by libraries that understand Kotlin's defaults, nullability, and sealed types more directly.
Bottom Line
For most developers searching "Kotlin JSON serialization and formatting libraries," the practical answer is to start with kotlinx.serialization. It is the best default for modern Kotlin, it handles both model serialization and JSON formatting cleanly, and it scales from tiny scripts to multiplatform apps. Reach for Jackson when your JVM stack already depends on Jackson, choose Moshi when an existing Android codebase is built around it, and keep Gson for legacy compatibility rather than new architecture.
Need help with your JSON?
Try our JSON Formatter tool to automatically identify and fix syntax errors in your JSON. JSON Formatter tool