JSON to Scala Converter
Generate Scala case classes from a JSON sample. Each object becomes a case class with typed fields (String, Int, Double, Boolean), nullable values are wrapped in Option[T], and arrays become List[T]. Nested objects are promoted to their own case classes, so a deeply nested payload turns into a clean, ordered set of immutable definitions ready for a JSON library like circe or play-json.
How to use the JSON to Scala Converter
Paste a representative JSON object and set the Root class name to match your domain type, for example User or Event. Click Generate. The output is a set of Scala case class definitions: one for the root object and one for each nested object, ordered so that every class is declared before it is referenced.
Field types are inferred from the sampled values. Strings become String, booleans become Boolean, and numbers split into Int or Double depending on whether the value has a fractional part. Any value that is null in the sample is wrapped as Option[T] — None at runtime — because a missing or null field maps to Option in idiomatic Scala. Arrays become List[T], and an array of objects produces a dedicated element case class used as the list's type parameter. Use Copy to take the result, or Example to load a payload that exercises nesting, a null field, and a list of objects.
Scala case classes, Option, and JSON
A case class is Scala's natural shape for a data record: it is immutable by default, comes with a generated equals, hashCode, toString, and copy, and supports pattern matching out of the box. JSON libraries in the Scala ecosystem — circe, play-json, zio-json — can derive an encoder and decoder for a case class automatically, which is why modelling a payload as case classes is the first step in almost every Scala service that consumes JSON. This generator turns a real sample directly into those definitions.
The most important inference decision is nullability. Scala discourages null; the idiomatic way to represent an optional value is Option[T], where presence is Some(value) and absence is None. When this tool sees a JSON value of null, it cannot know the underlying type, so it emits Option[String] as a sensible default and you can refine the inner type if you know it. Fields that always have a concrete value are typed plainly, but in production code you may choose to widen any field that can be absent to Option as well — JSON decoders treat a missing key and an Option field consistently.
Number handling reflects a real gap between JSON and Scala. JSON has one numeric type; Scala has Int, Long, Double, BigDecimal and more. The generator picks Int for whole numbers and Double for fractional ones from the sample, which is correct for most payloads but worth reviewing for large identifiers (where you may want Long) or money (where BigDecimal avoids floating-point error). Arrays map to immutable List[T]. If you also target the JVM through Kotlin or Java, the same structural approach drives the JSON to TypeScript generator for front-end code.
Common use cases
- circe / play-json models — scaffold the case classes a JSON codec will derive an encoder and decoder for.
- Akka HTTP / http4s endpoints — model request and response bodies from example payloads.
- Spark and data pipelines — define a typed record for JSON read from a file, queue, or API.
- Nullable handling — get
Option[T]automatically for fields that appear as null in the sample. - Kafka consumers — turn an event schema sample into immutable case classes for the consumer.
- Onboarding — paste an unfamiliar JSON blob to read its structure as concise Scala.
Frequently asked questions
When does a field become Option[T]?
null in the sample. Scala favours Option over null, so a null maps to Option[T] (None at runtime). Because the underlying type is unknown for a null, the generator defaults the inner type to String — refine it if you know it.How are numbers typed?
Int and a number with a fractional part becomes Double. JSON has a single number type, so review large IDs (you may want Long) and monetary values (BigDecimal) by hand.What about arrays and nested objects?
List[T], an immutable collection. Each nested object becomes its own case class named after the key, and an array of objects produces an element case class used as the list type parameter.Will circe or play-json work with the output directly?
deriveDecoder or a Json.format in play-json) and the generated classes serialize without further changes.