A Kotlin multiplatform library for JSON serialization providing type-safe JSON parsing and object serialization
—
Kotlin DSL for building JSON structures programmatically with type-safe, fluent APIs. The builder DSL provides an intuitive way to construct JsonObject and JsonArray instances without manually managing collections.
Create JsonObject instances using a type-safe builder DSL.
/**
* Build a JsonObject using a type-safe DSL
* @param builderAction Lambda with receiver for JsonObjectBuilder
* @return Constructed JsonObject
*/
fun buildJsonObject(builderAction: JsonObjectBuilder.() -> Unit): JsonObject
/**
* Builder for constructing JsonObject instances
*/
class JsonObjectBuilder {
/**
* Put a JsonElement value for the given key
* @param key Property name
* @param element JsonElement value to store
* @return Previous value associated with key, or null
*/
fun put(key: String, element: JsonElement): JsonElement?
/**
* Put a Boolean value for the given key
* @param key Property name
* @param value Boolean value to store (null creates JsonNull)
* @return Previous value associated with key, or null
*/
fun put(key: String, value: Boolean?): JsonElement?
/**
* Put a Number value for the given key
* @param key Property name
* @param value Number value to store (null creates JsonNull)
* @return Previous value associated with key, or null
*/
fun put(key: String, value: Number?): JsonElement?
/**
* Put a String value for the given key
* @param key Property name
* @param value String value to store (null creates JsonNull)
* @return Previous value associated with key, or null
*/
fun put(key: String, value: String?): JsonElement?
/**
* Put a null value for the given key
* @param key Property name
* @param value Must be null
* @return Previous value associated with key, or null
*/
@ExperimentalSerializationApi
fun put(key: String, value: Nothing?): JsonElement?
/**
* Put a nested JsonObject for the given key using builder DSL
* @param key Property name
* @param builderAction Lambda to build nested JsonObject
* @return Previous value associated with key, or null
*/
fun putJsonObject(key: String, builderAction: JsonObjectBuilder.() -> Unit): JsonElement?
/**
* Put a nested JsonArray for the given key using builder DSL
* @param key Property name
* @param builderAction Lambda to build nested JsonArray
* @return Previous value associated with key, or null
*/
fun putJsonArray(key: String, builderAction: JsonArrayBuilder.() -> Unit): JsonElement?
}Usage Examples:
import kotlinx.serialization.json.*
// Basic object construction
val userJson = buildJsonObject {
put("id", 1)
put("name", "Alice")
put("email", "alice@example.com")
put("active", true)
put("lastLogin", null as String?) // Creates JsonNull
}
// Nested objects and arrays
val productJson = buildJsonObject {
put("id", 12345)
put("name", "Laptop")
put("price", 999.99)
putJsonObject("specifications") {
put("cpu", "Intel i7")
put("ram", "16GB")
put("storage", "512GB SSD")
}
putJsonArray("tags") {
add("electronics")
add("computers")
add("portable")
}
putJsonArray("reviews") {
addJsonObject {
put("author", "John")
put("rating", 5)
put("comment", "Great laptop!")
}
addJsonObject {
put("author", "Jane")
put("rating", 4)
put("comment", "Good value")
}
}
}
// Result:
// {
// "id": 12345,
// "name": "Laptop",
// "price": 999.99,
// "specifications": {
// "cpu": "Intel i7",
// "ram": "16GB",
// "storage": "512GB SSD"
// },
// "tags": ["electronics", "computers", "portable"],
// "reviews": [
// {"author": "John", "rating": 5, "comment": "Great laptop!"},
// {"author": "Jane", "rating": 4, "comment": "Good value"}
// ]
// }Create JsonArray instances using a type-safe builder DSL.
/**
* Build a JsonArray using a type-safe DSL
* @param builderAction Lambda with receiver for JsonArrayBuilder
* @return Constructed JsonArray
*/
fun buildJsonArray(builderAction: JsonArrayBuilder.() -> Unit): JsonArray
/**
* Builder for constructing JsonArray instances
*/
class JsonArrayBuilder {
/**
* Add a JsonElement to the array
* @param element JsonElement to add
* @return Always true (consistent with MutableList.add)
*/
fun add(element: JsonElement): Boolean
/**
* Add a Boolean value to the array
* @param value Boolean value to add (null creates JsonNull)
* @return Always true
*/
fun add(value: Boolean?): Boolean
/**
* Add a Number value to the array
* @param value Number value to add (null creates JsonNull)
* @return Always true
*/
fun add(value: Number?): Boolean
/**
* Add a String value to the array
* @param value String value to add (null creates JsonNull)
* @return Always true
*/
fun add(value: String?): Boolean
/**
* Add a null value to the array
* @param value Must be null
* @return Always true
*/
@ExperimentalSerializationApi
fun add(value: Nothing?): Boolean
/**
* Add all JsonElements from a collection to the array
* @param elements Collection of JsonElements to add
* @return True if array was modified
*/
@ExperimentalSerializationApi
fun addAll(elements: Collection<JsonElement>): Boolean
/**
* Add all String values from a collection to the array
* @param values Collection of String values to add
* @return True if array was modified
*/
@ExperimentalSerializationApi
fun addAll(values: Collection<String?>): Boolean
/**
* Add all Boolean values from a collection to the array
* @param values Collection of Boolean values to add
* @return True if array was modified
*/
@ExperimentalSerializationApi
fun addAll(values: Collection<Boolean?>): Boolean
/**
* Add all Number values from a collection to the array
* @param values Collection of Number values to add
* @return True if array was modified
*/
@ExperimentalSerializationApi
fun addAll(values: Collection<Number?>): Boolean
/**
* Add a nested JsonObject to the array using builder DSL
* @param builderAction Lambda to build nested JsonObject
* @return Always true
*/
fun addJsonObject(builderAction: JsonObjectBuilder.() -> Unit): Boolean
/**
* Add a nested JsonArray to the array using builder DSL
* @param builderAction Lambda to build nested JsonArray
* @return Always true
*/
fun addJsonArray(builderAction: JsonArrayBuilder.() -> Unit): Boolean
}Usage Examples:
import kotlinx.serialization.json.*
// Basic array construction
val numbersJson = buildJsonArray {
add(1)
add(2.5)
add(3)
add(null as Number?) // Creates JsonNull
}
// Mixed type array
val mixedJson = buildJsonArray {
add("hello")
add(42)
add(true)
add(null as String?)
addJsonObject {
put("type", "embedded")
put("value", 100)
}
addJsonArray {
add("nested")
add("array")
}
}
// Bulk operations (experimental)
val bulkJson = buildJsonArray {
addAll(listOf("apple", "banana", "cherry"))
addAll(listOf(1, 2, 3, 4, 5))
addAll(listOf(true, false, null))
}
// Complex nested structure
val dataJson = buildJsonArray {
addJsonObject {
put("id", 1)
put("name", "Alice")
putJsonArray("hobbies") {
add("reading")
add("gaming")
}
}
addJsonObject {
put("id", 2)
put("name", "Bob")
putJsonArray("hobbies") {
add("sports")
add("music")
}
}
}
// Result:
// [
// {
// "id": 1,
// "name": "Alice",
// "hobbies": ["reading", "gaming"]
// },
// {
// "id": 2,
// "name": "Bob",
// "hobbies": ["sports", "music"]
// }
// ]Complex JSON structures using nested builders and conditional logic.
import kotlinx.serialization.json.*
fun buildUserProfile(
user: User,
includePrivateInfo: Boolean = false,
includePreferences: Boolean = true
): JsonObject = buildJsonObject {
put("id", user.id)
put("username", user.username)
put("displayName", user.displayName)
if (includePrivateInfo) {
put("email", user.email)
put("phone", user.phone)
}
putJsonObject("profile") {
put("bio", user.bio)
put("avatar", user.avatarUrl)
put("joinDate", user.joinDate.toString())
putJsonArray("badges") {
user.badges.forEach { badge ->
addJsonObject {
put("id", badge.id)
put("name", badge.name)
put("earned", badge.earnedDate.toString())
}
}
}
}
if (includePreferences && user.preferences.isNotEmpty()) {
putJsonObject("preferences") {
user.preferences.forEach { (key, value) ->
when (value) {
is String -> put(key, value)
is Number -> put(key, value)
is Boolean -> put(key, value)
else -> put(key, value.toString())
}
}
}
}
putJsonArray("recentActivity") {
user.recentActivities.take(10).forEach { activity ->
addJsonObject {
put("type", activity.type)
put("timestamp", activity.timestamp.toString())
put("data", Json.encodeToJsonElement(activity.data))
}
}
}
}Combining DSL builders with kotlinx.serialization for hybrid approaches.
import kotlinx.serialization.*
import kotlinx.serialization.json.*
@Serializable
data class ApiResponse<T>(
val success: Boolean,
val data: T?,
val error: String?
)
fun <T> buildApiResponse(
data: T? = null,
error: String? = null,
metadata: Map<String, Any> = emptyMap()
): JsonObject = buildJsonObject {
put("success", data != null)
put("timestamp", System.currentTimeMillis())
if (data != null) {
put("data", Json.encodeToJsonElement(data))
}
if (error != null) {
put("error", error)
}
if (metadata.isNotEmpty()) {
putJsonObject("metadata") {
metadata.forEach { (key, value) ->
when (value) {
is JsonElement -> put(key, value)
is String -> put(key, value)
is Number -> put(key, value)
is Boolean -> put(key, value)
else -> put(key, Json.encodeToJsonElement(value))
}
}
}
}
}
// Usage
val response = buildApiResponse(
data = listOf("item1", "item2", "item3"),
metadata = mapOf(
"requestId" to "req-123",
"processingTime" to 150,
"cached" to false
)
)import kotlinx.serialization.json.*
fun buildDynamicJson(properties: Map<String, Any?>): JsonObject = buildJsonObject {
properties.forEach { (key, value) ->
when (value) {
null -> put(key, null as String?)
is String -> put(key, value)
is Number -> put(key, value)
is Boolean -> put(key, value)
is List<*> -> putJsonArray(key) {
value.forEach { item ->
when (item) {
is String -> add(item)
is Number -> add(item)
is Boolean -> add(item)
else -> add(item.toString())
}
}
}
is Map<*, *> -> putJsonObject(key) {
value.forEach { (nestedKey, nestedValue) ->
put(nestedKey.toString(), nestedValue.toString())
}
}
else -> put(key, value.toString())
}
}
}import kotlinx.serialization.json.*
fun buildConditionalJson(
baseData: Map<String, String>,
includeTimestamp: Boolean = true,
includeDebug: Boolean = false,
userRole: String? = null
): JsonObject = buildJsonObject {
// Always include base data
baseData.forEach { (key, value) ->
put(key, value)
}
// Conditional timestamp
if (includeTimestamp) {
put("timestamp", System.currentTimeMillis())
}
// Debug information
if (includeDebug) {
putJsonObject("debug") {
put("buildTime", System.currentTimeMillis())
put("jvmVersion", System.getProperty("java.version"))
put("kotlinVersion", KotlinVersion.CURRENT.toString())
}
}
// Role-based data
when (userRole) {
"admin" -> {
put("adminLevel", true)
putJsonArray("permissions") {
add("read")
add("write")
add("delete")
add("admin")
}
}
"user" -> {
put("adminLevel", false)
putJsonArray("permissions") {
add("read")
add("write")
}
}
"guest" -> {
put("adminLevel", false)
putJsonArray("permissions") {
add("read")
}
}
null -> {
// No role-specific data
}
}
}Install with Tessl CLI
npx tessl i tessl/maven-org-jetbrains-kotlinx--kotlinx-serialization-json-jvm