JSON1 / JSON to Kotlin
JSON to Kotlin
Generate Kotlin data classes with kotlinx.serialization from a JSON sample. A SerialName annotation is added only where the JSON key differs from the property name.
Processed locally·Your data never leaves your device
InputJSON
ReadyOutputKotlin
Converted output appears here as you type.
Good to know
- Every record in an array is inspected, not just the first, so a field that appears in only some of them is typed as optional rather than required.
- Identical nested shapes are emitted once and reused, and reserved words are renamed to something legal in this language.
About this tool
A Kotlin data class gives you equals, hashCode, copy, and destructuring from the declaration alone, which is most of what a DTO needs. This generates one per object in the sample with kotlinx.serialization annotations, val throughout, and nested objects hoisted into classes of their own.
Kotlin's type system is the reason its output differs from the other JVM target here. Nullability is part of the type rather than a convention, so JSON's optionality maps onto it exactly:
LongEvery JSON integer, not Int. JSON has no width limit, and a 64-bit id from an API is common enough that narrowing by default would be the wrong bet.DoubleAny number with a fractional part. Kotlin has no decimal type, so a monetary value needs BigDecimal and a custom serializer.String?A nullable or sometimes-absent field. The question mark is enforced by the compiler, so the absent case cannot be forgotten the way it can in Java.= nullOptional properties also get a default, which is what lets kotlinx.serialization accept a payload where the key is missing entirely rather than present and null.Any?A field that was null in every record. Nothing narrower would be honest — replace it once you have a sample where the field is populated.
- When is a SerialName annotation added?
- Only when the JSON key differs from the property name after camelCasing —
first_namebecomingfirstNameneeds one,titledoes not. Annotating everything would triple the length of a simple model for no gain. - Why kotlinx.serialization and not Moshi or Gson?
- It is the JetBrains-maintained option and the only one that understands Kotlin nullability and default values without reflection. That matters specifically here: Gson constructs objects through Unsafe, so it will happily leave a non-null
Stringholding null and the failure surfaces somewhere else entirely. Switching to Moshi means changing annotations, not the class. - Why is
List<Any>a problem under @Serializable? - Because kotlinx.serialization needs a serializer for every type at compile time and
Anyhas none. A heterogeneous or always-empty array produces one, and it will not compile until you either give the element a real type or register a contextual serializer. The generator emits it rather than guessing, so the gap is visible instead of silent. - Could these be value classes or a sealed hierarchy?
- Not from a sample. A
value classneeds to know an id is semantically distinct from any other Long, and a sealed hierarchy needs to know which field discriminates the variants. Neither fact is in the JSON — they are decisions about your domain, and the data class is the honest starting point for both. - How are optional fields decided?
- Every record in an array is inspected, not just the first. A field that appears in some records and not others is typed as optional, and a value that is sometimes null widens accordingly. Generators that read only the first element get this wrong on exactly the payloads where it matters.
- What happens to a key that is a reserved word?
- It is renamed to something legal in the target language, and where the language supports it, an annotation records the original JSON key so serialisation still round-trips.
Related tools
- JSON to DartGenerate Dart classes with fromJson and toJson from a JSON sample. Every nested object gets its own class, so decoding a payload never leaves you holding a raw map.
- JSON to SwiftGenerate Swift structs conforming to Codable from a JSON sample. CodingKeys are emitted only when a key differs from its property name, so simple models stay readable.
- TOML to JSONConvert TOML to formatted JSON. Tables, table arrays, dotted keys, inline tables, and multi-line arrays are all supported.