
High-performance JSON serializer/deserializer with zero extra allocations, zero-copy buffer wrapping, map/object inlining, polymorphic value-subclass support, and advanced parser hooks.
Fast and powerful implementation of JSON format for kotlinx-serialization.
@JsonInline to inline its serialized form. Only final classes and Map instances can be inlined.ChunkedDecoder) and Float/Double types (still allocates much less than most serializers). On Kotlin/JS, it may allocate much more — not much we can do about it.Buffer interface that requires only size property and get method to be implemented.JsonReader). That allows implementing simple and efficient content-based polymorphism without extra allocations of JsonElement.@Serializable sealed interface Base
@Serializable value class Foo(val int: Int): Base
val s = ZeroJson.encodeToString<Base>(Foo(42))
println(s)
// { "type": "Foo", "value": 42 }
println(ZeroJson.decodeFromString<Base>(s))
// 42
dynamic supportInputStream/OutputStream is not recommended. Nearly all I/O libraries and frameworks provide access to underlying array or buffer abstractions. Wrapping these is the intended way to use this library. For any streaming workload, we recommend using the original kotlinx-serialization-json instead.prettyPrint optionSetup Google repository (zero-json uses androidx.collection:collection under the hood):
repositories {
google()
}This option allows you to use all the features specific to zero-json.
implementation("io.github.adokky:zero-json-core:0.5.2")Compatible with kotlinx-serialization-json 1.9.0.
Not available for JavaScript, though WasmJs is supported.
implementation("io.github.adokky:zero-json-kotlinx:0.5.2")Exclude the original kotlinx-serialization-json:
configurations.configureEach {
resolutionStrategy {
exclude("org.jetbrains.kotlinx", "kotlinx-serialization-json")
}
}Both zero-json-core and zero-json-kotlinx can be used simultaneously.
StructureKind.MAP and StructureKind.CLASS
Quick example:
@Serializable
class Person(
val name: String,
val age: Int,
@JsonInline val location: Location,
@JsonInline val extra: Map<String, String>?,
)
@Serializable
class Location(@JsonInline val country: Country, val city: String)
@Serializable
class Country(
@JsonNames("countryName") val name: String,
@JsonNames("countryCode") val code: Int
)
ZeroJson.encodeToString(
Person(
name = "Alex",
age = 44,
location = Location(
country = Country("Dreamland", 1234),
city = "SimCity"
),
extra = mapOf("avatar" to "https://cdn.example/profile_picture23535")
)
)Result:
{
"name": "Alex",
"age": 44,
"countryName": "Dreamland",
"countryCode": 1234,
"city": "SimCity",
"avatar": "https://cdn.example/profile_picture23535"
}zero-json is built for fast UTF-8 encoding/decoding — super common in network-related workloads. It's tuned for JVM backend services which handle tons of client requests, so serialization is one of the main bottlenecks. Client apps rarely hit serialization limits — they're more bogged down by UI or network delays.
Benchmarks use JMH, so results may vary on other platforms.
Decoding (smaller is better):
bytes_kotlinx 136.218 ± 1.453 us/op
bytes_zjson 107.799 ± 0.891 us/op
string_kotlinx 80.194 ± 0.751 us/op
string_zjson 100.707 ± 0.770 us/op
tree_kotlinx 42.197 ± 3.291 us/op
tree_zjson 28.922 ± 0.574 us/op
Encoding (smaller is better):
bytes_kotlinx 36.517 ± 0.587 us/op
bytes_zjson 29.325 ± 0.553 us/op
string_kotlinx 27.550 ± 0.635 us/op
string_zjson 42.241 ± 4.009 us/op
tree_kotlinx 31.760 ± 3.394 us/op
tree_zjson 19.541 ± 0.352 us/op
bytes:
decodeFromStream, encodeToStream (ByteArrayOutputStream/ByteArrayInputStream)decodeFromBuffer, encodeToBuffer (ArrayBuffer)string - decodeFromString, encodeToString
tree - decodeFromJsonElement, encodeToJsonElement
Fast and powerful implementation of JSON format for kotlinx-serialization.
@JsonInline to inline its serialized form. Only final classes and Map instances can be inlined.ChunkedDecoder) and Float/Double types (still allocates much less than most serializers). On Kotlin/JS, it may allocate much more — not much we can do about it.Buffer interface that requires only size property and get method to be implemented.JsonReader). That allows implementing simple and efficient content-based polymorphism without extra allocations of JsonElement.@Serializable sealed interface Base
@Serializable value class Foo(val int: Int): Base
val s = ZeroJson.encodeToString<Base>(Foo(42))
println(s)
// { "type": "Foo", "value": 42 }
println(ZeroJson.decodeFromString<Base>(s))
// 42
dynamic supportInputStream/OutputStream is not recommended. Nearly all I/O libraries and frameworks provide access to underlying array or buffer abstractions. Wrapping these is the intended way to use this library. For any streaming workload, we recommend using the original kotlinx-serialization-json instead.prettyPrint optionSetup Google repository (zero-json uses androidx.collection:collection under the hood):
repositories {
google()
}This option allows you to use all the features specific to zero-json.
implementation("io.github.adokky:zero-json-core:0.5.2")Compatible with kotlinx-serialization-json 1.9.0.
Not available for JavaScript, though WasmJs is supported.
implementation("io.github.adokky:zero-json-kotlinx:0.5.2")Exclude the original kotlinx-serialization-json:
configurations.configureEach {
resolutionStrategy {
exclude("org.jetbrains.kotlinx", "kotlinx-serialization-json")
}
}Both zero-json-core and zero-json-kotlinx can be used simultaneously.
StructureKind.MAP and StructureKind.CLASS
Quick example:
@Serializable
class Person(
val name: String,
val age: Int,
@JsonInline val location: Location,
@JsonInline val extra: Map<String, String>?,
)
@Serializable
class Location(@JsonInline val country: Country, val city: String)
@Serializable
class Country(
@JsonNames("countryName") val name: String,
@JsonNames("countryCode") val code: Int
)
ZeroJson.encodeToString(
Person(
name = "Alex",
age = 44,
location = Location(
country = Country("Dreamland", 1234),
city = "SimCity"
),
extra = mapOf("avatar" to "https://cdn.example/profile_picture23535")
)
)Result:
{
"name": "Alex",
"age": 44,
"countryName": "Dreamland",
"countryCode": 1234,
"city": "SimCity",
"avatar": "https://cdn.example/profile_picture23535"
}zero-json is built for fast UTF-8 encoding/decoding — super common in network-related workloads. It's tuned for JVM backend services which handle tons of client requests, so serialization is one of the main bottlenecks. Client apps rarely hit serialization limits — they're more bogged down by UI or network delays.
Benchmarks use JMH, so results may vary on other platforms.
Decoding (smaller is better):
bytes_kotlinx 136.218 ± 1.453 us/op
bytes_zjson 107.799 ± 0.891 us/op
string_kotlinx 80.194 ± 0.751 us/op
string_zjson 100.707 ± 0.770 us/op
tree_kotlinx 42.197 ± 3.291 us/op
tree_zjson 28.922 ± 0.574 us/op
Encoding (smaller is better):
bytes_kotlinx 36.517 ± 0.587 us/op
bytes_zjson 29.325 ± 0.553 us/op
string_kotlinx 27.550 ± 0.635 us/op
string_zjson 42.241 ± 4.009 us/op
tree_kotlinx 31.760 ± 3.394 us/op
tree_zjson 19.541 ± 0.352 us/op
bytes:
decodeFromStream, encodeToStream (ByteArrayOutputStream/ByteArrayInputStream)decodeFromBuffer, encodeToBuffer (ArrayBuffer)string - decodeFromString, encodeToString
tree - decodeFromJsonElement, encodeToJsonElement