🧬 Mastering kotlinx.serialization
: The Native Kotlin JSON Library
In modern Android and Kotlin development, efficient data parsing and serialization are essential. While libraries like Gson and Moshi have long dominated this space, Kotlin has its own native solution — kotlinx.serialization
.
📦 What is kotlinx.serialization
?
kotlinx.serialization
is a Kotlin-first, multiplatform library for converting objects to and from formats like JSON, ProtoBuf, CBOR, and more.
It:
- Is statically typed and compile-time safe
- Works seamlessly with Kotlin data classes
- Supports multiplatform projects (JVM, JS, Native)
- Avoids reflection (making it fast!)
🚀 Getting Started
Step 1: Add dependencies
Add these to your build.gradle.kts
(Kotlin DSL):
1
2
3
4
5
6
7
| plugins {
kotlin("plugin.serialization") version "1.9.0"
}
dependencies {
implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:1.6.0")
}
|
🛠️ Basic Usage
Define a serializable data class:
1
2
3
4
| import kotlinx.serialization.Serializable
@Serializable
data class User(val name: String, val age: Int)
|
Serialize to JSON:
1
2
3
4
5
6
| import kotlinx.serialization.encodeToString
import kotlinx.serialization.json.Json
val user = User("Alice", 25)
val jsonString = Json.encodeToString(user)
println(jsonString) // {"name":"Alice","age":25}
|
Deserialize from JSON:
1
2
3
4
| import kotlinx.serialization.decodeFromString
val decodedUser = Json.decodeFromString<User>(jsonString)
println(decodedUser.name) // Alice
|
🌐 JSON Customization Options
Pretty Print
1
2
| val json = Json { prettyPrint = true }
val prettyJson = json.encodeToString(user)
|
Ignore Unknown Keys
1
| val json = Json { ignoreUnknownKeys = true }
|
Default Values
1
2
| @Serializable
data class Product(val name: String, val price: Double = 0.0)
|
If the JSON is missing price
, it will default to 0.0
.
🎯 Key Features
🔖 Field Aliasing
Use @SerialName
to map JSON fields with different names:
1
2
3
4
5
| @Serializable
data class User(
@SerialName("full_name") val name: String,
val age: Int
)
|
🧲 Optional and Nullable Fields
1
2
3
4
5
| @Serializable
data class Profile(
val bio: String? = null,
val email: String = "unknown@example.com"
)
|
🧬 Lists and Nested Objects
List
1
2
3
| val users = listOf(User("Alice", 25), User("Bob", 30))
val json = Json.encodeToString(users)
val backToList = Json.decodeFromString<List<User>>(json)
|
Nested Objects
1
2
3
4
5
| @Serializable
data class Address(val city: String, val zip: String)
@Serializable
data class Person(val name: String, val address: Address)
|
⚙️ Json Configuration Options
1
2
3
4
5
6
7
| val json = Json {
prettyPrint = true
encodeDefaults = true
isLenient = true
ignoreUnknownKeys = true
explicitNulls = false
}
|
🔍 Advanced: Custom Serializers
For non-standard types like Date
, you can create a custom serializer:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
| object DateSerializer : KSerializer<Date> {
override val descriptor: SerialDescriptor = PrimitiveSerialDescriptor("Date", PrimitiveKind.STRING)
override fun serialize(encoder: Encoder, value: Date) {
val format = SimpleDateFormat("yyyy-MM-dd")
encoder.encodeString(format.format(value))
}
override fun deserialize(decoder: Decoder): Date {
val format = SimpleDateFormat("yyyy-MM-dd")
return format.parse(decoder.decodeString())!!
}
}
@Serializable
data class Event(@Serializable(with = DateSerializer::class) val date: Date)
|
🔐 kotlinx.serialization vs Gson vs Moshi
Feature |
Gson |
Moshi |
kotlinx.serialization |
Kotlin-native |
❌ |
⚠️ Partial |
✅ Yes |
Reflection-free |
❌ |
✅ |
✅ |
Multiplatform |
❌ |
❌ |
✅ |
Performance |
Medium |
High |
Very High |
Compile-time safety |
❌ |
✅ |
✅ |
🧩 Use Cases
- ✅ Android JSON parsing
- ✅ Multiplatform mobile projects (KMM)
- ✅ Saving structured data to disk
- ✅ State persistence and caching
🧪 With Retrofit
Retrofit doesn’t support kotlinx.serialization
natively, but you can use a custom converter like:
1
| implementation("com.jakewharton.retrofit:retrofit2-kotlinx-serialization-converter:0.8.0")
|
Then use it like:
1
2
3
4
| val retrofit = Retrofit.Builder()
.baseUrl("https://api.example.com/")
.addConverterFactory(Json.asConverterFactory("application/json".toMediaType()))
.build()
|
🛡️ Best Practices
- Use
@SerialName
for field renaming
- Enable
ignoreUnknownKeys
for API flexibility
- Prefer
kotlinx.serialization
for modern Kotlin-first apps
- Create custom serializers for non-standard or legacy formats
📚 Conclusion
kotlinx.serialization
is a powerful, modern, and type-safe serialization library made for Kotlin developers. Its compile-time safety, performance, and multiplatform support make it ideal for today’s Android and Kotlin Multiplatform projects.
If you’re starting a new Kotlin-based app, this should be your go-to serialization library.