Skip to content
vic

eeue56/json-to-elm

Create Elm type aliases and decoders based on JSON input

eeue56/json-to-elm.json
{
"createdAt": "2016-02-21T19:36:17Z",
"defaultBranch": "master",
"description": "Create Elm type aliases and decoders based on JSON input",
"fullName": "eeue56/json-to-elm",
"homepage": "http://json2elm.com",
"language": "Elm",
"name": "json-to-elm",
"pushedAt": "2018-04-13T21:42:53Z",
"stargazersCount": 278,
"topics": [],
"updatedAt": "2025-11-11T16:18:27Z",
"url": "https://github.com/eeue56/json-to-elm"
}

Create Elm type aliases and decoders based on JSON input

This project allows you to automate the creation of:

  • type aliases from JSON data
  • decoders from type aliases and some union types
  • encoders from type aliases and some union types

You can run this program as a command line tool:

Noahs-MacBook-Pro:json-to-elm noah$ python generate.py ../elm-static-site/examples/Users.elm
decodeUser : Decoder User
decodeUser =
succeed User
|: ("name" := string)
|: ("location" := string)
|: ("age" := int)
encodeUser : User -> Json.Encode.Value
encodeUser record =
object
[ ("name", string record.name)
, ("location", string record.location)
, ("age", int record.age)
]

You can also give it a json file.

or you can use the following functions:

print_everything takes in a string containing a JSON object, and a top-level name for the alias it will generate.

It will then recursively generate aliases and decoders for all the JSON objects in the json object.

create_type_alias takes a json object, and returns a list of type aliases needed for that object

create_decoder takes a type alias as a string, along with a prefix to use for custom decoders, and if the encoded fields have snakecase or not, and generates just the decoder for that type alias

create_encoder takes a type alias as a string, along with a prefix to use for custom encoders, and if the encoded fields have snakecase or not, and generates just the encoder for that type alias

create_union_type_decoder takes a union type definition as a string, and will generate the decoder needed if the json value is a string

create_union_type_encoder takes a union type definition as a string, and will generate the encoder needed if the json value is a string

print_everything(
"""
{ "name" : "Noah"
, "age" : 23
, "location" :
{ "name" : "sweden"
, "days" : 45
}
}
"""
, alias_name = "Person")

generates

type alias Location =
{ name : String
, days : Int
}
type alias Person =
{ age : Int
, name : String
, location : Location
}
decodeLocation : Json.Decode.Decoder Location
decodeLocation =
Json.Decode.succeed Location
|: ("name" := Json.Decode.string)
|: ("days" := Json.Decode.int)
decodePerson : Json.Decode.Decoder Person
decodePerson =
Json.Decode.succeed Person
|: ("age" := Json.Decode.int)
|: ("name" := Json.Decode.string)
|: ("location" := decodeLocation)
encodeLocation : Location -> Json.Encode.Value
encodeLocation record =
Json.Encode.object
[ ("name", Json.Decode.string record.name)
, ("days", Json.Decode.int record.days)
]
encodePerson : Person -> Json.Encode.Value
encodePerson record =
Json.Encode.object
[ ("age", Json.Decode.int record.age)
, ("name", Json.Decode.string record.name)
, ("location", encodeLocation record.location)
]

for more examples of this, see the test function

print(create_union_type_decoder('type Suit = Hearts | Diamonds | Spades | Clubs'))
print(create_union_type_encoder('type Suit = Hearts | Diamonds | Spades | Clubs'))

will print

decodeSuit : Json.Decode.Decoder Suit
decodeSuit =
let
decodeToType string =
case string of
"Hearts" -> Result.Ok Hearts
"Diamonds" -> Result.Ok Diamonds
"Spades" -> Result.Ok Spades
"Clubs" -> Result.Ok Clubs
_ -> Result.Err ("Not valid pattern for decoder to Suit. Pattern: " ++ (toString string))
in
Json.Decode.customDecoder Json.Decode.string decodeToType
encodeSuit : Suit -> Json.Encode.Value
encodeSuit item =
case item of
Hearts -> Json.Encode.string "Hearts"
Diamonds -> Json.Encode.string "Diamonds"
Spades -> Json.Encode.string "Spades"
Clubs -> Json.Encode.string "Clubs"