JSON to Elm
Paste JSON and instantly get clean, idiomatic Elm record type aliases with inferred field types, nested records, and lists.
Example
Given this JSON input:
{
"user": { "id": 1, "name": "Bob" },
"tags": ["a", "b"]
}the tool emits idiomatic Elm:
type alias Root =
{ user : User
, tags : List String
}
type alias User =
{ id : Int
, name : String
}How it works
The tool parses your JSON, walks every value to infer Elm types (Int/Float/Bool/String, nested record aliases, and List types), and emits type aliases with the root named Root. Identical record shapes are deduplicated into a single alias.
Good to know
JSON to Elm turns a sample JSON payload into ready-to-paste Elm record type aliases, inferring each field's type (Int, Float, Bool, String), building nested aliases for sub-objects, and wrapping arrays in List. It's aimed at Elm developers who consume external APIs and want a head start on the type definitions that feed their JSON decoders, rather than hand-writing every record by hand.
Reach for it when you have a real response from an endpoint and need a faithful starting shape for your model. Paste the JSON, click Convert, and read the output top-down: the entry point is always type alias Root, and every capitalized type referenced inside it (like User or Order) is defined in its own alias further down. Array element types are singularized from the field name, so a tags array of strings becomes List String and an orders array becomes List Order.
A few things shape how to interpret the result and where to be careful:
- Because JSON has one number type, the tool decides Int vs Float per value:
14 becomes Int but 14.0 becomes Float. If a numeric field is sometimes whole and sometimes fractional, pick a sample where it shows the decimal so you don't get a too-narrow Int. - A JSON
null infers as Maybe () and an empty array as List (), both placeholders you'll want to replace with the real element type once you know it. - Records with identical field shapes are deduplicated into one shared alias, which keeps output compact but means two semantically different objects that happen to match may collapse together.
One practical caveat: the tool generates the type aliases only, not the matching JSON decoders, so you'll still write (or generate separately) the Json.Decode code that maps these types from raw JSON. Everything runs in your browser, so it's safe to paste production responses, but the output is only as accurate as the sample you feed it. Use a representative payload that exercises optional fields and realistic number formats before committing the types to your codebase.
Frequently asked questions
How are numbers mapped to Elm types?
Whole numbers like 30 become Int, while numbers with a decimal point like 9.5 become Float. Because JSON does not distinguish the two, a value such as 14.0 is treated as Float and 14 as Int, so use representative sample data.
What happens with nested objects and arrays?
Each nested object becomes its own type alias named after its field (singularized for array items), and arrays become List types. Objects with an identical field shape are deduplicated into a single shared alias.
Is my data uploaded anywhere?
No — it runs entirely in your browser. Your input never leaves your device and it works offline once loaded.
Is it free?
Yes, completely free with no sign-up and no limits.
People also ask
What is an Elm type alias and why use one for JSON?
A type alias in Elm gives a name to a record shape, for example a record with name and age fields. Naming the shape lets the compiler check that your JSON decoders and the rest of your code agree on the structure of the data.
Does this tool also generate Elm JSON decoders?
No. It produces the record type aliases only. You still need to write or generate the matching Json.Decode pipeline that turns raw JSON into values of those types.
How does Elm handle a JSON field that can be null?
In Elm an absent or null value is typically modeled with Maybe, so a nullable field becomes Maybe SomeType. This tool emits Maybe () for a null sample, which you should replace with the actual underlying type.
Why is my array showing as List () in the output?
That happens when the sample array is empty, so there is no element to infer a type from. Provide a sample with at least one item and the tool will produce a concrete element type such as List String or List Order.
What gets used as the name for nested record types?
Each nested object is named after its field, and array item types are singularized from the field name. So an owner object becomes type alias Owner and items in an orders array become Order.
Can a single number field be both Int and Float in Elm?
No, an Elm record field has one fixed type. Because the tool infers Int from whole numbers and Float from decimals, choose a sample value that reflects the wider type if the field can hold fractional values.
Is it safe to paste private API responses into this tool?
The conversion runs entirely client-side in your browser and the input is not sent to any server, and it works offline once the page has loaded. As with any tool, follow your own organization's data handling policies.
What does the Root type alias represent in the output?
Root is the name given to the top-level shape of your JSON. It is the entry point that references every other generated alias, so reading the output starting from Root shows the full structure.
Related tools