Kotlin Help

Serialize built-in types

The Kotlin serialization library supports a variety of built-in types, including basic types such as primitives and strings, as well as certain standard library classes. The following sections describe these types in detail and show how to serialize them.

Basic types

Kotlin serialization provides built-in serializers for types that are represented as a single value in serialized data. This includes primitives, strings, and enums.

For example, here's how you can serialize a Long type:

// Imports the necessary library declarations import kotlinx.serialization.* import kotlinx.serialization.json.* //sampleStart @Serializable class Data(val signature: Long) fun main() { val data = Data(0x1CAFE2FEED0BABE0) println(Json.encodeToString(data)) // {"signature":2067120338512882656} } //sampleEnd

Numbers

You can serialize all Kotlin number types, including integers and floating-point numbers, using their natural JSON representations:

import kotlinx.serialization.* import kotlinx.serialization.json.* import kotlin.math.PI //sampleStart @Serializable class Data( val answer: Int, val pi: Double ) fun main() { val data = Data(42, PI) println(Json.encodeToString(data)) // {"answer":42,"pi":3.141592653589793} } //sampleEnd

Unsigned numbers

Kotlin serialization supports Kotlin's unsigned integer types like UByte and UInt. In JSON, these values are serialized as regular JSON numbers and preserve their full unsigned range:

import kotlinx.serialization.* import kotlinx.serialization.json.* //sampleStart @Serializable class Counter(val counted: UByte, val description: String) fun main() { val counted = 239.toUByte() println(Json.encodeToString(Counter(counted, "tries"))) // {"counted":239,"description":"tries"} } //sampleEnd

Long numbers as strings

You can represent Long numbers as strings in JSON. This is useful in JavaScript environments, where JavaScript's Number type can't precisely represent all Kotlin Long values, which may lead to precision loss.

Use LongAsStringSerializer with the @Serializable annotation to encode Long values as strings in JSON:

import kotlinx.serialization.* import kotlinx.serialization.builtins.* import kotlinx.serialization.json.* //sampleStart @Serializable class Data( @Serializable(LongAsStringSerializer::class) val signature: Long ) fun main() { val data = Data(0x1CAFE2FEED0BABE0) println(Json.encodeToString(data)) // {"signature":"2067120338512882656"} } //sampleEnd

Enum classes

All enum classes are serializable by default without the @Serializable annotation. When serialized in JSON, an enum is encoded as a string:

import kotlinx.serialization.* import kotlinx.serialization.json.* //sampleStart // The @Serializable annotation isn't required for enum classes enum class Status { SUPPORTED } @Serializable class Project(val name: String, val status: Status) fun main() { val data = Project("kotlinx.serialization", Status.SUPPORTED) println(Json.encodeToString(data)) // {"name":"kotlinx.serialization","status":"SUPPORTED"} } //sampleEnd

Customize serial names of enum entries

To customize the serial names of enum entries, use the @SerialName annotation and mark the enum class with @Serializable:

import kotlinx.serialization.* import kotlinx.serialization.json.* //sampleStart // Requires the @Serializable annotation because of @SerialName @Serializable enum class Status { @SerialName("maintained") SUPPORTED } @Serializable class Project(val name: String, val status: Status) fun main() { val data = Project("kotlinx.serialization", Status.SUPPORTED) println(Json.encodeToString(data)) // {"name":"kotlinx.serialization","status":"maintained"} } //sampleEnd

For more information on customizing serial names, see Customize serial names.

Standard library types

Kotlin serialization supports several types from the standard library, but some classes, such as ranges and the Regex class, aren't supported.

Pair and triple

You can serialize the Pair and Triple classes from the Kotlin standard library:

import kotlinx.serialization.* import kotlinx.serialization.json.* //sampleStart @Serializable class Project(val name: String) fun main() { val pair = 1 to Project("kotlinx.serialization") println(Json.encodeToString(pair)) // {"first":1,"second":{"name":"kotlinx.serialization"}} } //sampleEnd

Collections

Kotlin serialization supports collection types, including both read-only and mutable variants of List, Set, and Map. It also supports their concrete implementations such as ArrayList and LinkedHashSet, as well as generic and primitive array types. The way these collections are represented depends on the serialization format.

In JSON, lists and sets are serialized as JSON arrays, and maps are represented as JSON objects.

Kotlin uses the declared type to deserialize JSON. During deserialization, the type of the resulting object is determined by the static type specified in the source code. This type can be either the type of the property or the type parameter of the decoding function.

Serialize lists

Kotlin serialization serializes List types as JSON arrays. Here's an example with a list of classes:

import kotlinx.serialization.* import kotlinx.serialization.json.* //sampleStart @Serializable class Project(val name: String) fun main() { val list = listOf( Project("kotlinx.serialization"), Project("kotlinx.coroutines") ) println(Json.encodeToString(list)) // [{"name":"kotlinx.serialization"},{"name":"kotlinx.coroutines"}] } //sampleEnd

Serialize sets

Set types are serialized as JSON arrays, just like List types:

import kotlinx.serialization.* import kotlinx.serialization.json.* //sampleStart @Serializable class Project(val name: String) fun main() { val set = setOf( Project("kotlinx.serialization"), Project("kotlinx.coroutines") ) println(Json.encodeToString(set)) // [{"name":"kotlinx.serialization"},{"name":"kotlinx.coroutines"}] } //sampleEnd

Serialize maps

Kotlin serialization supports Map types with primitive or enum keys:

import kotlinx.serialization.* import kotlinx.serialization.json.* //sampleStart @Serializable class Project(val name: String) fun main() { // Creates a map with Int keys val map = mapOf( 1 to Project("kotlinx.serialization"), 2 to Project("kotlinx.coroutines") ) println(Json.encodeToString(map)) // {"1":{"name":"kotlinx.serialization"},"2":{"name":"kotlinx.coroutines"}} } //sampleEnd

Map serialization depends on the format. In JSON, maps are represented as objects. Since JSON object keys are always strings, keys are encoded as strings even if they are numbers in Kotlin. Other formats, such as CBOR, support maps with non-primitive keys and preserve them as such.

Deserialization behavior of collections

Kotlin uses the declared type to deserialize JSON. For example, with collections, a List preserves duplicates, while a Set enforces uniqueness:

import kotlinx.serialization.* import kotlinx.serialization.json.* //sampleStart @Serializable data class Data( val a: List<Int>, val b: Set<Int> ) fun main() { val data = Json.decodeFromString<Data>(""" { "a": [42, 42], "b": [42, 42] } """) // Duplicates are removed from data.b because the Set type enforces unique elements println(data) // Data(a=[42, 42], b=[42]) } //sampleEnd

Unit and singleton objects

Kotlin's Unit type and other singleton objects are serializable. A singleton is a class with only one instance, where the state is defined by the object itself rather than by external properties. In JSON, singleton objects are serialized as empty structures:

import kotlinx.serialization.* import kotlinx.serialization.json.* //sampleStart @Serializable object SerializationVersion { val libraryVersion: String = "1.0.0" } fun main() { println(Json.encodeToString(SerializationVersion)) // {} println(Json.encodeToString(Unit)) // {} } //sampleEnd

Duration and Instant

Kotlin's Duration type is serialized to a string using the ISO-8601-2 format:

import kotlinx.serialization.* import kotlinx.serialization.json.* import kotlin.time.* //sampleStart fun main() { val duration = 1000.toDuration(DurationUnit.SECONDS) println(Json.encodeToString(duration)) // "PT16M40S" } //sampleEnd

You can also serialize Kotlin's Instant type as a string representing a point in time using the ISO-8601-1 format:

import kotlinx.serialization.* import kotlinx.serialization.json.* import kotlin.time.* //sampleStart fun main() { val instant = Instant.fromEpochMilliseconds(1607505416124) println(Json.encodeToString(instant)) // "2020-12-09T09:16:56.124Z" } //sampleEnd

Nothing

The Nothing type is serializable by default. It has no instances, so encoding or decoding it throws an exception. Use Nothing when a type is syntactically required, but not involved in serialization, like in a polymorphic hierarchy with a generic base type:

import kotlinx.serialization.* import kotlinx.serialization.builtins.* import kotlinx.serialization.json.* //sampleStart @Serializable sealed class ParametrizedParent<out R> { @Serializable data class ChildWithoutParameter(val value: Int) : ParametrizedParent<Nothing>() } fun main() { println(Json.encodeToString(ParametrizedParent.ChildWithoutParameter(42))) // {"value":42} } //sampleEnd

What's next

23 June 2026