JSON to Kotlin Data Class

Generate a Kotlin data class from a JSON document.

JSON Input
Kotlin Data Class Output
Kotlin Data Class output appears here

Related Tools

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 class declarations with constructor-declared val properties
  • Nullable fields use Kotlin's ? type suffix with a = null default, not a placeholder value
  • Nested objects become their own named data classes
  • @SerialName annotations 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.