← All courses

Data Models & Serialization

🗓 May 31, 2026 ⏱ 2 min read

Shared models: write once, use everywhere

One of the biggest wins of KMP is defining your data models a single time in commonMain. The same User class is then used by your Android app, your iOS app, your networking and your database — no more keeping two copies in sync.

data class User(
    val id: Int,
    val name: String,
    val email: String
)

kotlinx.serialization

To turn objects into JSON (and back) in a multiplatform way, Kotlin provides kotlinx.serialization. You annotate a class with @Serializable and the library handles the conversion on every platform.

import kotlinx.serialization.Serializable

@Serializable
data class User(
    val id: Int,
    val name: String,
    val email: String
)

Encoding and decoding

import kotlinx.serialization.json.Json

val json = Json { ignoreUnknownKeys = true }   // tolerate extra fields

// object -> JSON string
val text = json.encodeToString(User(1, "Anand", "a@x.com"))

// JSON string -> object
val user = json.decodeFromString<User>(text)

ignoreUnknownKeys = true is important in real apps: it stops decoding from crashing when the server sends extra fields you don’t use.

Handling API field names

When the JSON key differs from your Kotlin property, map it with @SerialName:

@Serializable
data class User(
    val id: Int,
    @SerialName("full_name") val name: String,   // JSON key is full_name
    val email: String? = null                    // optional / nullable
)

Nested and list models

@Serializable
data class ApiResponse(
    val page: Int,
    val users: List<User>     // lists and nested objects just work
)

Why this matters for KMP

Because serialization runs in commonMain, both your Android and iOS apps parse JSON with the exact same code and the exact same rules. A change to a model updates everywhere at once — a major reduction in bugs.

Common mistakes

  • Forgetting @Serializable (you get a runtime/compile error).
  • Not setting ignoreUnknownKeys, so the app crashes on extra server fields.
  • Forgetting to make genuinely optional fields nullable (?) with a default.
Summary: Define models once in common code and annotate them @Serializable. Use kotlinx.serialization’s Json to encode/decode on every platform, set ignoreUnknownKeys, and map API names with @SerialName.