100% local — your data never leaves your browser

JSON to Scala — Case Classes, Keys Intact

Turn a JSON sample into Scala case classes. Field names keep the JSON keys, in backticks where the language needs them, ready for your codec.

Instant Private Zero cookies

JSON input

Scala output

What this tool does

A JSON sample becomes Scala case classes, one per object.

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

case class Address(
  city: String
)

An array of objects at the root also gets a name: type Root = List[RootItem], a top-level alias, which is Scala 3.

Backticks keep the key

{ "content-type": "text/html", "class": 1 }
case class Root(
  `content-type`: String,
  `class`: Long
)

Scala takes anything between backticks as an identifier, so the field name can stay exactly what the JSON said. That is not a cosmetic choice: circe, zio-json and upickle all derive the JSON name from the field name, so this case class reads your payload as it is, with no annotation and no custom decoder.

The alternative — renaming to contentType — would require a configured codec to map it back, and a sample cannot tell which library you use.

Types, and the two that are honest about their ignorance

Integers become Long and decimals Double: a JSON number fits neither Int nor Float reliably, and widening beats a silent overflow.

null, an empty array and a mixed array all become Any, which is exactly as vague as the sample. Any is uncomfortable in Scala, and that discomfort is the point — it marks the fields where the document told you nothing, and it does not pretend otherwise.

What a sample cannot say

No field is an Option, none has a default value, and nothing is a sealed trait: a single document shows one shape. If two payloads differ by a key, that is a union you model yourself — and the place where a generated type stops being useful and your own design starts.

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 are some field names in backticks?
Because Scala allows any identifier between them, and that keeps the JSON key as the field name. `content-type` and `class` would be illegal otherwise. It matters beyond looks: derivation-based libraries such as circe use the field name as the JSON name, so keeping it means the case class decodes your document without a single annotation.
Which JSON library is this meant for?
Any of the derivation ones — circe, zio-json, upickle — because they all read the field names. No imports or annotations are emitted, so nothing here ties you to one. With Jackson\u2019s Scala module the same applies; only a field you rename by hand needs `@JsonProperty`.
Why is nothing an `Option`?
Because a sample shows presence, never absence. Every field was there, so every field is required — and `Option[String]` is the edit you make once you know the key can be missing. Making everything optional up front would turn every access into a `getOrElse` for no reason the document supports.

Related converters