Kotlin Help

Serialize JSON with I/O sources

The Kotlin serialization library provides APIs for working with JVM streams and kotlinx-io or Okio sources and sinks.

You can use these APIs to serialize and deserialize JSON directly from I/O sources without creating intermediate strings. These APIs use UTF-8 encoding and throw SerializationException for invalid JSON data and IOException for I/O failures.

When working with I/O resources, it's important to close them properly to prevent resource leaks. You can do this with the .use() function, which closes the resource automatically when the operation completes.

Serialize JSON to JVM output streams

Use the .encodeToStream() extension function to serialize JSON directly to a JVM OutputStream:

// Imports declarations from the serialization library import kotlinx.serialization.* import kotlinx.serialization.json.* import java.io.FileOutputStream @Serializable data class Project(val name: String, val stars: Int) fun main() { val project = Project("kotlinx.serialization", 9000) // Creates an OutputStream for the project.json file FileOutputStream("project.json").use { output -> // Serializes the project instance into the OutputStream Json.encodeToStream(project, output) } }

In this example, the JSON representation of Project is serialized into the project.json file.

Deserialize JSON from JVM input streams

To deserialize JSON directly from a JVM InputStream, use the .decodeFromStream() extension function:

// Imports declarations from the serialization library import kotlinx.serialization.* import kotlinx.serialization.json.* import java.io.FileInputStream @Serializable data class Project(val name: String, val stars: Int) fun main() { // Opens an InputStream FileInputStream("project.json").use { input -> // Deserializes the JSON contents of the InputStream into a Project instance val project = Json.decodeFromStream<Project>(input) // Prints the deserialized Project instance println(project) } }

In this example, the JSON contents of the input stream are deserialized into a single Project instance.

If your input contains multiple JSON objects in a top-level JSON array or as whitespace-separated objects, you can use .decodeToSequence() to process the elements lazily. This lets you handle each value as it is parsed, for example:

// Imports declarations from the serialization library import kotlinx.serialization.* import kotlinx.serialization.json.* import java.io.FileInputStream @Serializable data class Project(val name: String, val stars: Int) fun main() { // Opens an InputStream for the projects.json file containing a JSON array of Project objects FileInputStream("projects.json").use { input -> // Lazily deserializes each Project from the InputStream val projects = Json.decodeToSequence<Project>(input) // Processes elements one by one for (project in projects) { println(project) } } }

JSON serialization with kotlinx-io and Okio

In addition to JVM streams, you can work with JSON using I/O types, such as kotlinx.io.Sink and kotlinx.io.Source from the kotlinx-io library (currently in Alpha), and okio.BufferedSink and okio.BufferedSource from the Okio library.

You can use the following Json extension functions to read and write JSON directly through these I/O types:

The next sections cover examples using kotlinx-io types with these APIs.
You can use Okio types similarly with their corresponding okio.BufferedSink and okio.BufferedSource APIs.

Add dependencies for kotlinx-io and Okio

To use the extension functions with kotlinx-io or Okio types, add the corresponding dependencies:

Add dependencies for kotlinx-io

// build.gradle(.kts) dependencies { implementation("org.jetbrains.kotlinx:kotlinx-serialization-json-io:1.11.0") implementation("org.jetbrains.kotlinx:kotlinx-io-core:0.9.0") }
<!-- pom.xml --> <dependencies> <dependency> <groupId>org.jetbrains.kotlinx</groupId> <artifactId>kotlinx-serialization-json-io</artifactId> <version>1.11.0</version> </dependency> <dependency> <groupId>org.jetbrains.kotlinx</groupId> <artifactId>kotlinx-io-core</artifactId> <version>0.9.0</version> </dependency> </dependencies>

Add dependencies for Okio

// build.gradle(.kts) dependencies { implementation("org.jetbrains.kotlinx:kotlinx-serialization-json-okio:1.11.0") implementation("com.squareup.okio:okio:3.16.2") }
<!-- pom.xml --> <dependencies> <dependency> <groupId>org.jetbrains.kotlinx</groupId> <artifactId>kotlinx-serialization-json-okio</artifactId> <version>1.11.0</version> </dependency> <dependency> <groupId>com.squareup.okio</groupId> <artifactId>okio</artifactId> <version>3.16.2</version> </dependency> </dependencies>

Serialize JSON to Sinks

To serialize JSON to a Sink, use the .encodeToSink() function:

// Imports declarations from the serialization library import kotlinx.serialization.* import kotlinx.serialization.json.* // Imports declarations for kotlinx-io types and JSON I/O support import kotlinx.serialization.json.io.* import kotlinx.io.* import kotlinx.io.files.* @Serializable data class Project(val name: String, val stars: Int) @OptIn(ExperimentalSerializationApi::class) fun main() { val project = Project("kotlinx.serialization", 9000) // Creates a Sink for the project.json file val path = Path("project.json") SystemFileSystem.sink(path).buffered().use { sink: Sink -> // Serializes the Project instance directly into a Sink Json.encodeToSink(project, sink) } }

Deserialize JSON from Sources

To deserialize JSON from a Source, use the .decodeFromSource() function:

// Imports declarations from the serialization library import kotlinx.serialization.* import kotlinx.serialization.json.* // Imports declarations for kotlinx-io types and JSON I/O support import kotlinx.serialization.json.io.* import kotlinx.io.* import kotlinx.io.files.* @Serializable data class Project(val name: String, val stars: Int) @OptIn(ExperimentalSerializationApi::class) fun main() { // Opens a Source for the project.json file val path = Path("project.json") SystemFileSystem.source(path).buffered().use { source: Source -> // Deserializes a Project instance directly from a Source val project = Json.decodeFromSource<Project>(source) println(project) } }

If your input contains a large JSON array or multiple top-level JSON objects, you can turn a Source into a lazily decoded Sequence<T> with the .decodeSourceToSequence() function.

// Imports declarations from the serialization library import kotlinx.serialization.* import kotlinx.serialization.json.* // Imports declarations for kotlinx-io types and JSON I/O support import kotlinx.serialization.json.io.* import kotlinx.io.* import kotlinx.io.files.* @Serializable data class Project(val name: String, val stars: Int) @OptIn(ExperimentalSerializationApi::class) fun main() { // Opens a Source for the projects.json file containing multiple JSON objects val path = Path("projects.json") SystemFileSystem.source(path).buffered().use { source: Source -> // Lazily deserializes each Project as it is read from the Source val projects: Sequence<Project> = Json.decodeSourceToSequence(source) for (project in projects) { println(project) } } }

What's next

10 June 2026