FormatterHQ

JSON to Scala Case Class Generator

Generate Scala 3 case classes from JSON with Option for optional values, Seq for arrays, and circe Encoder and Decoder derivation.

Input JSON
Output SCALA
Ready.

How to use the JSON to Scala

  1. Paste your JSON sample (an object, or an array of objects) into the Input editor, or use Sample, Upload file or Load URL, or press Sample to try one.
  2. Set the Top-level class name, for example Task; it is converted to PascalCase. Nested types are named after their property keys.
  3. Leave Types only (no helpers) off to derive circe Encoder and Decoder instances; tick it for plain case classes.
  4. Press Generate (it also re-runs automatically as you edit), then use Copy or Download.

JSON to Scala case classes with circe

In Scala, JSON models are usually case classes, and circe is one of the most popular libraries for encoding and decoding them. This JSON to Scala generator writes Scala 3 case classes from a sample and, in full mode, adds derives Encoder.AsObject, Decoder to each one, so circe can convert them without any hand-written codecs.

Example

{ "id": 42, "title": "Write docs", "done": false,
  "owner": { "name": "Ada", "email": null },
  "subtasks": [ { "title": "Outline", "estimate": 2 }, { "title": "Draft" } ] }
package quicktype

import io.circe.syntax._
import io.circe._

case class Task (
    val id : Long,
    val title : String,
    val done : Boolean,
    val owner : Owner,
    val subtasks : Seq[Subtask]
) derives Encoder.AsObject, Decoder

case class Subtask (
    val title : String,
    val estimate : Option[Long] = None
) derives Encoder.AsObject, Decoder

The optional estimate is Option[Long] with a default of None. The derives clause is Scala 3 syntax; it asks the compiler to generate circe's type class instances.

How types are inferred

Whole numbers become Long, decimals Double, arrays Seq[T] and nested objects their own case classes. Scala 3 union types are used for mixed values: an array of numbers and strings becomes Seq[X] with type X = Long | String, and the generated codecs handle both alternatives. Fields missing from some objects are wrapped in Option with a None default, so you can construct instances without them in tests.

Decoding and encoding

import io.circe.parser.decode
import io.circe.syntax._

val result: Either[io.circe.Error, Task] = decode[Task](jsonString)
result.foreach(task => println(task.asJson.spaces2))

Add circe-core, circe-generic and circe-parser to your build. Decoding returns an Either, so a mismatch produces a DecodingFailure with the path to the offending field instead of an exception.

Notes and adjustments

  • Scala 2: derives is not available. Remove it and use io.circe.generic.auto._ or deriveDecoder / deriveEncoder from circe-generic.
  • val in parameters is redundant for case classes and can be removed.
  • Dates stay String; circe has built-in codecs for java.time types such as OffsetDateTime if you change the field type.
  • Null-only fields become Option[Json]; replace them with a concrete Option type when you know it.
  • Other libraries: the plain case classes work with Play JSON, ZIO JSON or uPickle with their own derivation mechanisms.

For a JVM alternative, JSON to Kotlin or JSON to Java produce equivalent models. Validate input with the JSON Validator. Generation runs in your browser.

Frequently asked questions

Does the generated Scala code work with Scala 2?
The derives clause is Scala 3 only. For Scala 2, remove it and use circe-generic’s automatic or semi-automatic derivation.
Which dependencies are needed?
circe-core, circe-generic and circe-parser. The output imports io.circe._ and io.circe.syntax._.
How are optional fields represented?
As Option types with a default of None, which circe decodes as None when the key is missing or null.
Can I use the case classes with another JSON library?
Yes. Tick Types only to get plain case classes, then add the derivation your library uses, such as ZIO JSON or Play JSON.

Last updated September 26, 2026

Related tools