Skip to main content

JSON to Kotlin Data Class — kotlinx.serialization, Gson, or Moshi

JSON to Kotlin data class — paste JSON, get val properties, camelCase fields, nullable T?, nested classes, and kotlinx.serialization @SerialName, Gson @SerializedName, or Moshi @Json annotations.

  • Runs locally
  • Category Developer & DevOps
  • Best for Formatting, validating, shrinking, or inspecting code-adjacent text.
Examples:
How types, annotations & nullability are inferred

Each JSON object becomes a Kotlin data class with camelCase val properties; nested objects lift into their own named data classes (User.address → UserAddress). When the Kotlin property name differs from the wire key (snake_case, kebab-case), an @SerialName (kotlinx.serialization), @SerializedName (Gson), or @Json (Moshi) annotation preserves the exact key so (de)serialisation round-trips. Integer numbers infer Int (or Long when they exceed 32-bit range); fractional numbers infer Double; a number that is sometimes whole and sometimes fractional widens to Double. Arrays of objects fold into ONE class — keys missing from some elements (or seen as null) become nullable T?. A value that is only ever null types as Any?. Turn on "default values" to get = null on nullable properties and = emptyList() on lists, so the class is constructable without supplying optionals.

What this tool does

Paste any JSON payload — a Retrofit response, a Ktor route body, a Firebase document, a third-party REST API — and get back a clean set of Kotlin `data class` declarations ready to drop into a `.kt` file. Properties are generated as `val` (immutable by default, the idiomatic Kotlin choice for DTOs), JSON keys are camelCased into valid identifiers (`site_admin` becomes `siteAdmin`, `is-active` becomes `isActive`, `created_at` becomes `createdAt`), and class names are PascalCased. Pick the serializer your project already uses: kotlinx.serialization adds `@Serializable` to every class plus `@SerialName("site_admin")` wherever the Kotlin name differs from the wire key; Gson uses `@SerializedName`; Moshi uses `@Json(name = "...")`; or choose None for annotation-free output. The annotation is attached only when the camelCase name actually diverges from the original key, so a field like `name` stays clean and round-trips without help. Numbers are split, not flattened: an integer that fits in a 32-bit `Int` infers `Int`, a larger integer (millisecond timestamps, snowflake IDs) infers `Long`, a fractional value infers `Double`, and a field that is whole in one sample and decimal in another widens to `Double`. Nullability follows Kotlin's type system precisely — a key that is missing from some elements of an object array, or seen as JSON `null`, becomes `T?`, and a value that is only ever null types as `Any?`. Arrays of objects fold into ONE shared data class, so `[{"a":1},{"a":1,"b":2}]` produces a single type with both fields (and `b` nullable), not two near-duplicates. Nested objects lift into their own named classes (`User.address` becomes `UserAddress`), and the optional "default values" switch adds `= null` to nullable properties and `= emptyList()` to lists so the class is constructable without supplying optionals. Everything runs in your browser — the JSON never touches a server.

Tool details

Input
Text + Numbers + Structured content
The page exposes text boxes, numeric controls, file pickers, or structured inputs depending on the tool.
Output
Live result + Copy + Download
The result area focuses on usable output, with copy, download, or preview actions when supported.
Privacy
Browser-side processing
The main tool logic does not call an external API, so inputs normally stay in the current tab.
Save / share
Shareable URL state
Key settings are encoded in the URL so another person can reopen the same setup.
Performance budget
Initial JS <= 25 KB
No WASM budget is declared, keeping the tool quick to open on mobile.
Best fit
Developer & DevOps · Developer
Category and role tags drive related tools, internal links, and quick fit checks.

How to use

  1. 1. Input

    Paste or drop your content into the tool panel.

  2. 2. Process

    Click the button. All processing is local in your browser.

  3. 3. Copy / Download

    Copy the result or download to disk in one click.

How JSON to Kotlin Data Class fits into your work

Use it in the small gaps between coding, reviewing, debugging, and shipping.

Developer jobs

  • Formatting, validating, shrinking, or inspecting code-adjacent text.
  • Preparing snippets for documentation, tickets, commits, or handoff.
  • Checking a small payload quickly without switching tools.

Developer checks

  • Run irreversible transforms like minify or obfuscate on a copy.
  • Keep secrets out of pasted snippets unless the tool explicitly stays local.
  • Use your normal tests or linter before shipping transformed code.

Good next steps

These links move the current task into a more complete workflow.

  1. 1 JSON to Java Class JSON to Java POJO, record, or Lombok @Data — paste JSON, get camelCase fields with getters/setters, Jackson @JsonProperty or Gson @SerializedName, nested classes, primitive vs boxed inference. Open
  2. 2 JSON to C# Class JSON to C# class or record — paste JSON, get PascalCase properties with System.Text.Json or Newtonsoft attributes, nested classes, nullable T?, init setters, DateTime detection. Open
  3. 3 JSON to Go Struct JSON to Go struct — paste JSON, get typed structs with json tags, exported fields, nested sub-structs, pointers for nullable, int64 and omitempty options. Open

Real-world use cases

  • Type a Retrofit response without hand-writing the model

    You're calling a third-party REST API from an Android app with Retrofit + Moshi, and the response has 25+ fields in snake_case. Curl it once, paste the JSON here, set the root name to `OrderResponse`, pick Moshi. Every `created_at`-style key gets `@Json(name = ...)` so the converter binds it, nested objects lift into their own classes, and optional fields become `T?`. Drop the output into `OrderResponse.kt`, declare `@GET("orders") suspend fun orders(): OrderResponse`, and you get a fully-typed result instead of a `Map<String, Any?>` you cast your way through field by field.

  • Build kotlinx.serialization models for a Ktor service

    You're writing a Ktor backend and want a request and response model for a new endpoint. Paste the sample request body, name the root `CreateOrderRequest`, keep kotlinx.serialization. You get a `@Serializable data class` with `@SerialName` on the renamed fields and the exact imports it needs. Turn on default values so missing keys decode cleanly instead of throwing, and the model is forward-compatible the day a new optional field appears in the payload.

  • Catch which webhook fields are actually optional

    A vendor's webhook sometimes includes `cancelled_at` and sometimes omits it. Log a handful of payloads, paste them as a JSON array, and the array-fold detection marks `cancelled_at` as missing in some elements — so it becomes `String?` instead of a non-null field that would crash on deserialization. In your handler a `?.let { }` now cleanly distinguishes "cancelled" from "still active" instead of guessing whether a default value means the field was absent.

  • Migrate a Java DTO to an idiomatic Kotlin data class

    You're porting an Android module from Java to Kotlin and a Gson-bound POJO needs to become a data class. Grab a representative JSON response, paste it, choose Gson, and you get `@SerializedName`-annotated `val` properties in a single `data class` — no getters, no `equals`/`hashCode` boilerplate, and `copy()` for free. The new class is a fraction of the line count of the Java original and reads exactly like the JSON it models.

  • Replace a Map<String, Any?> with a real type

    Legacy Kotlin does `val data: Map<String, Any?> = parse(body)` and reaches in with casts like `data["id"] as String`, losing every compile-time check and inviting `ClassCastException` at runtime. Capture one representative response, paste it, generate the data class, and replace the map. Now `Int`, `Long`, and `Double` are inferred per field, nullability is explicit, and the compiler catches a renamed key at build time instead of in production.

Common pitfalls

  • Pasting a single object and expecting some fields to be nullable. A single object has no missing-key signal, so every field is non-null unless its value is literally null. Nullable inference only kicks in across an array of objects where some elements carry a key and others don't. To explore optionality from one sample, wrap it as `[{...}]`.

  • Leaving a money or precise-decimal field as `Double`. The tool infers `Double` for any fractional number, but `Double` is binary floating point and will misrepresent values like 0.1 or a currency total. For money, change those fields to `BigDecimal` after generating — JSON carries no signal that a number needs exact base-10 precision.

  • Forgetting the kotlinx.serialization Gradle plugin and runtime. The `@Serializable` annotation needs both the `org.jetbrains.kotlin.plugin.serialization` Gradle plugin and the `kotlinx-serialization-json` dependency; without the plugin the code won't compile. If you only want the plain class, pick the None annotation style instead.

  • Deleting an @SerialName / @Json / @SerializedName annotation and expecting binding to still work. The annotation is what maps `site_admin` (wire) to `siteAdmin` (property). Remove it and the serializer will look for a `siteAdmin` key that doesn't exist, leaving the field null or failing to decode. Keep the annotation or configure a global naming strategy instead.

Privacy

Your JSON never leaves this browser tab. Parsing and type inference use the browser's built-in `JSON.parse`; there is no network call and no analytics on the textarea content. The Share link encodes your input and the root class name into the URL so a result is reproducible — that means YOU decide when to share. If the payload is sensitive (internal IDs, customer data, prod responses), copy the generated Kotlin instead of sharing the link. Only your option choices (annotation style, default values) are stored in localStorage so your preferred style persists across visits.

FAQ

Tool combos

Folks in your role tend to reach for these alongside this tool.

Made by Toolora · 100% client-side · Updated 2026-06-13