JSON to Kotlin Data Class
Generate a Kotlin data class from a JSON document.
Related Tools
Generate a Java POJO class with getters and setters from a JSON document.
Generate a Rust struct with serde derive attributes from a JSON document.
Generate TypeScript interfaces or type aliases from JSON.
Beautify and pretty-print JSON with configurable indentation.
Convert CSV to JSON with delimiter detection and header toggle.
Generate Go structs with JSON tags from a JSON document.
Documentation
What is JSON to Kotlin?
This tool converts a JSON sample into Kotlin data class declarations — one per object level, using val constructor properties instead of Java-style getters and setters. Data classes get free equals(), hashCode(), toString(), and copy(), which is exactly what a JSON-backed model needs.
How it works
Nested objects each become their own data class, printed child-first. Numbers become Int or Double depending on whether the sample value has a fractional part, and arrays become List<T>. A field whose sample was null is typed nullable (T?) with a default of null, matching Kotlin's null-safety model rather than using a sentinel value. When a JSON key isn't a valid or idiomatic Kotlin property name — or camelCasing it would produce a different string than the raw key — the generator adds @SerialName("originalKey") so the property stays idiomatic while still deserializing correctly. Property names that would collide with a Kotlin keyword get a Value suffix, and class names colliding with built-ins (List, String, Any, etc.) get a Model suffix.
Features
- Emits idiomatic
data classdeclarations with constructor-declaredvalproperties - Nullable fields use Kotlin's
?type suffix with a= nulldefault, not a placeholder value - Nested objects become their own named data classes
@SerialNameannotations only appear where the Kotlin property name would otherwise diverge from the JSON key- Reserved keyword and built-in-type collisions are automatically renamed so the output compiles as-is
Example
Input: { "id": 101, "username": "alice_dev", "isActive": true, "signupBonus": null, "address": { "city": "Berlin", "zipCode": "10115" }, "tags": ["admin", "beta"] }
Output:
data class Address(
val city: String,
val zipCode: String
)
data class Root(
val id: Int,
val username: String,
val isActive: Boolean,
val signupBonus: Any? = null,
val address: Address,
val tags: List<String>
)Common errors
A null sample value is typed as Any? since no concrete shape can be inferred from it — replace with a real type once you know what the field actually holds. An empty sample array produces List<Any?>. The generated @SerialName annotation is specific to kotlinx.serialization — if you're using Moshi or Gson instead, swap it for @Json(name = ...) or @SerializedName respectively; the class shape itself works unchanged with any of them.
Best practices
Keep data classes immutable (val, not var) — the generator already does this, and it pairs well with copy() for producing modified instances without mutating the original. Add @Serializable at the class level once you wire up kotlinx.serialization, and prefer sealed classes over nullable fields when a value is genuinely one of several known variants rather than simply optional.
Frequently Asked Questions
Why a data class instead of a regular class?▾
Kotlin data classes automatically generate equals(), hashCode(), toString(), and copy() — exactly what you want for a plain JSON-backed model, without writing that boilerplate by hand.
What does @SerialName do in the output?▾
When a JSON key isn't a valid or idiomatic Kotlin property name as-is, the generator adds @SerialName("original_key") (kotlinx.serialization's annotation) so the property can be camelCase in Kotlin while still deserializing the original JSON key correctly.
How are nullable fields represented?▾
A field whose sample value is null becomes a nullable type (T?) with a default of null, matching idiomatic Kotlin null-safety rather than using a sentinel value.
Does this work with Moshi or Gson instead of kotlinx.serialization?▾
The generated class itself (properties and types) works with any of them — only the @SerialName annotation is kotlinx.serialization-specific. Swap it for Moshi's @Json(name = ...) or Gson's @SerializedName if you're using a different library.