JSON to Kotlin
The result appears here.
Generate
Your document never leaves the browser.
Kotlin data classes for kotlinx.serialization, from a JSON sample — in your browser.
Paste a payload and get data classes ready for kotlinx.serialization on Kotlin 2.0 or later. They work the same on Android, the JVM and Kotlin Multiplatform, since the library runs on all three. The module needs the Kotlin serialization compiler plugin, as any @Serializable class does.
Each object becomes a @Serializable data class with val properties in camelCase, and each renamed key keeps its wire name in @SerialName, so order_id is orderId. Whole numbers are Long and numbers with a fraction Double.
Kotlin’s default Json configuration can tell a missing key from a null one, and the output uses that. note is present in both line items and null in one, so it is String? with no default: the key must be there. gift-wrap is absent from one, so it is Boolean? = null, which may be left out. The header comment spells out the same rule.
The sample, an order with two line items, pasted as the source
{
"order_id": 1042,
"placed_at": "2026-09-25T10:15:00Z",
"paid": true,
"customer": { "name": "Ada Lovelace", "email": "ada@example.com" },
"items": [
{ "sku": "PEN-01", "qty": 2, "price": 3.5, "note": null },
{ "sku": "INK-07", "qty": 1, "price": 12, "note": "Fragile", "gift-wrap": true }
]
}The data classes written for it
// Generated by myjsoneditor.com for kotlinx.serialization (Kotlin 2.0+).
// Decode with the default Json: explicitNulls = true, so a `T?` with no default is a
// required key that may be null, and `T? = null` is a key that may be absent.
package generated
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable
@Serializable
data class Customer(
val name: String,
val email: String,
)
@Serializable
data class Item(
val sku: String,
val qty: Long,
val price: Double,
val note: String?,
@SerialName("gift-wrap")
val giftWrap: Boolean? = null,
)
@Serializable
data class Root(
@SerialName("order_id")
val orderId: Long,
@SerialName("placed_at")
val placedAt: String,
val paid: Boolean,
val customer: Customer,
val items: List<Item>,
)The sample, with Serialization annotations off
// Generated by myjsoneditor.com as plain Kotlin data classes (Kotlin 2.0+).
// Add your JSON library's annotations; `T? = null` marks a key that may be absent.
package generated
data class Customer(
val name: String,
val email: String,
)
data class Item(
val sku: String,
val qty: Long,
val price: Double,
val note: String?,
val giftWrap: Boolean? = null, // JSON key: "gift-wrap"
)
data class Root(
val orderId: Long, // JSON key: "order_id"
val placedAt: String, // JSON key: "placed_at"
val paid: Boolean,
val customer: Customer,
val items: List<Item>,
)Option
Serialization annotations: on by default. Turn it off for plain data classes with no imports, to annotate for Moshi, Jackson or Gson yourself.
Option
Package: generated by default. Type your module’s package and the declaration at the top follows it.
An integer past Long becomes a JsonPrimitive, whose content property keeps every digit. A list of mixed values is List<JsonElement>, and a key seen only as null is a JsonElement too, each with a comment saying what was in the sample.
Nested classes are named from their keys, in the singular for what a list holds, so the items list is a List<Item>. If the same shape turns up twice, under different keys, it is still one data class. A key that is a Kotlin keyword is kept in backticks, so class stays `class` rather than being renamed. When a type in the document is called List, the standard one is written in full as kotlin.collections.List, so the two never collide.
A 20-digit account number, a mixed list, a null and a keyword
{ "account": 12345678901234567890, "codes": [1, "A"], "coupon": null, "class": "A" }JsonPrimitive, JsonElement and `class`
// Generated by myjsoneditor.com for kotlinx.serialization (Kotlin 2.0+).
// Decode with the default Json: explicitNulls = true, so a `T?` with no default is a
// required key that may be null, and `T? = null` is a key that may be absent.
package generated
import kotlinx.serialization.Serializable
import kotlinx.serialization.json.JsonElement
import kotlinx.serialization.json.JsonPrimitive
@Serializable
data class Root(
val account: JsonPrimitive, // past Long — .content keeps the digits
val codes: List<JsonElement>, // elements: one of: Long, String
val coupon: JsonElement, // only null was seen
val `class`: String,
)Inference and code generation both run inside this browser tab. The sample is never uploaded, stored on a server or logged, because the page has no server to send it to, and once loaded it carries on working with the connection off.
Json.decodeFromString<Root>(text), with your root class in place of Root. Add ignoreUnknownKeys = true to a Json instance to tolerate keys the sample did not have.
The shapes do. Turn off Serialization annotations and add the library’s own, such as @Json(name) for Moshi.
A sample cannot promise a value will stay in Int’s range, so whole numbers use Long. Narrow them where you know better.