FormatterHQ

JSON to Elm Decoder Generator

Generate Elm record type aliases, JSON decoders and encoders from a sample. Optional fields become Maybe values.

Input JSON
Output ELM
Ready.

How to use the JSON to Elm

  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 get decoders and encoders; tick it for the record type aliases alone.
  4. Press Generate (it also re-runs automatically as you edit), then use Copy or Download.

JSON to Elm: types and decoders

Elm never trusts incoming data: every JSON value must pass through a decoder that describes its exact shape, which is why Elm apps do not crash on unexpected API responses. Writing those decoders is also the most tedious part of Elm development. This JSON to Elm generator writes record type aliases and the matching decoders and encoders from a sample.

Example

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

Type aliases (types only):

type alias Task =
    { id : Int
    , title : String
    , done : Bool
    , owner : Owner
    , subtasks : List Subtask
    }

type alias Subtask =
    { title : String
    , estimate : Maybe Int
    }

The optional estimate is a Maybe Int. The full output also contains decoders written in the pipeline style, one per type, for example:

subtask : Jdec.Decoder Subtask
subtask =
    Jdec.succeed Subtask
        |> Jpipe.required "title" Jdec.string
        |> Jpipe.optional "estimate" (Jdec.nullable Jdec.int) Nothing

Setting up the module

  1. Install the pipeline package: elm install NoRedInk/elm-json-decode-pipeline.
  2. Save the output as QuickType.elm, or rename the module QuickType exposing (...) line to match your file.
  3. Decode with Json.Decode.decodeString task jsonString, which returns a Result you handle with a case expression.

The module also exports encoders built with Json.Encode, useful when sending the same data back to a server.

Custom types for mixed values

When a value can have different JSON types, the generator creates an Elm custom type instead of giving up. An array like [1, "a"] produces type X = IntegerInX Int | StringInX String, with a decoder that tries each variant using Jdec.oneOf. Pattern matching with case then forces you to handle every variant, which is exactly Elm's promise of no runtime exceptions. Field names that clash with Elm keywords or generated names are adjusted, so read the type alias carefully after generating.

Adjustments

  • Fields that are null in the sample become the unit type (); change them to Maybe String with a nullable decoder once you know the real type.
  • Dates remain String; decode them with a package such as rtfeldman/elm-iso8601-date-strings.
  • Record field order in the type alias must match the order of the pipeline steps, since Jdec.succeed Task uses the record constructor. Keep them aligned when editing.

Check your sample with the JSON Validator, and explore large responses with the JSON Viewer before generating. Everything runs in your browser.

Frequently asked questions

Which Elm packages does the generated code need?
elm/json and NoRedInk/elm-json-decode-pipeline for the pipeline-style decoders. The header comment in the output lists the install command.
Why does field order matter in Elm decoders?
Pipeline decoders call the record constructor with arguments in order, so the sequence of required and optional steps must match the order of fields in the type alias.
How are optional JSON fields decoded?
They use the optional pipeline step with a nullable decoder and default to Nothing, so the field type is Maybe.
Can I rename the module?
Yes. Change the module QuickType line to match your file name, such as module Api.Task exposing (..).

Last updated September 26, 2026

Related tools

XML to Elm Generate Elm type aliases with decoders from a XML sample instantly, with nested types detected automatically. JSON to Flow Generate Flow Flow type definitions from a JSON sample instantly, with nested types detected automatically. JSON to Go Generate Go structs with json tags from a JSON sample instantly, with nested types detected automatically. JSON to Haskell Generate Haskell records with Aeson instances from a JSON sample instantly, with nested types detected automatically. JSON to Java Generate Java POJO classes with getters and setters from a JSON sample instantly, with nested types detected automatically. JSON to JavaScript PropTypes Generate JavaScript PropTypes React PropTypes definitions from a JSON sample instantly, with nested types detected automatically. JSON to JSON Schema Generate JSON Schema a JSON Schema document from a JSON sample instantly, with nested types detected automatically. JSON to Kotlin Generate Kotlin data classes from a JSON sample instantly, with nested types detected automatically. JSON to Laravel Model & Migration Generate a Laravel Eloquent model ($fillable, casts, relations) and a matching migration from a sample JSON record. JSON to Mongoose Schema Generate a Mongoose schema and model from a sample JSON document, detecting Date, ObjectId, arrays and nested objects. JSON to Objective-C Generate Objective-C classes with properties from a JSON sample instantly, with nested types detected automatically. JSON to PHP Generate PHP classes with typed properties from a JSON sample instantly, with nested types detected automatically.