100% local — your data never leaves your browser

JSON to Kotlin — Data Classes You Can Paste

Turn a JSON sample into Kotlin data classes. Property names stay as the JSON wrote them, backticked where the language needs it, ready to compile.

Instant Private Zero cookies

JSON input

Kotlin output

What this tool does

A JSON sample becomes Kotlin data classes, one per object.

{ "id": 1, "firstName": "Ada", "address": { "city": "Paris" } }
data class Root(
    val id: Long,
    val firstName: String,
    val address: Address,
)

data class Address(
    val city: String,
)

Every property is a val: a decoded payload is a value. Data classes give you equals, hashCode, toString and copy() — the last one is how you change a field without mutating anything.

The key stays the key

Kotlin identifiers can be written between backticks, and that is enough to keep a JSON key exactly as it was:

data class Root(
    val `content-type`: String,
    val `class`: Long,
    val `2fa`: Boolean,
)

class is a keyword, content-type has a dash, 2fa starts with a digit — none of it matters inside backticks. With kotlinx.serialization the property name is the JSON name, so this decodes as is, with no annotation at all.

With Jackson or Moshi the property name is also what they look for, so the backticked names work there too. It is only if you decide to rename a property — contentType rather than `content-type` — that you need @JsonProperty("content-type") or @Json(name = "content-type") to point back at the key.

Types, and the ? that is not there

  • Integers become Long and decimals Double, which is what a JSON number can hold without argument.
  • null and unknown values become Any? — the only place a question mark appears, because it is the only place the sample showed one.
  • An empty or mixed array becomes List<Any>.

Nothing else is nullable and nothing has a default. A field that is sometimes absent is a ? and a = null you add yourself, once a second payload has told you what this one could not.

Two keys, two properties

Two keys that would collide as property names are kept apart rather than merged — the second takes a numbered suffix. Since the backticked name is the JSON name, collisions are rare here: they only happen when repair is unavoidable.

Private by design

Everything runs locally in your browser with JavaScript. Your data is never uploaded, which makes the tool safe for sensitive content, and it keeps working offline.

Frequently asked questions

Why is my property named `` `content-type` `` with backticks?
Because Kotlin lets an identifier be anything between backticks, and that is the way to keep the JSON key as the property name. With kotlinx.serialization the property name *is* the JSON name, so nothing else is needed. With Jackson or Moshi the same result needs an annotation — `@JsonProperty` or `@Json(name = …)` — added by hand.
Should the fields be `val` or `var`?
`val`, because a decoded payload is a value, not a form. Making everything mutable invites code that edits the object in place and then wonders which version it is looking at. Where you genuinely need to modify, `copy()` gives you a new instance with one field changed — the idiom data classes were made for.
Why no default values?
Because a default is a claim about what a missing key means, and one sample never shows a missing key. `= null` on a field would turn "absent" into "null" for the whole codebase. Adding it is one word once you know the API; guessing it is a decision nobody asked this tool to make.

Related converters