Automatic type declaration for JSON input data


Version on this page:
LTS Haskell 14.27:3.0.1
Stackage Nightly 2019-09-21:3.0.1
Latest on Hackage:3.1.2

See all snapshots json-autotype appears in

BSD-3-Clause licensed by Michal J. Gajda
Maintained by [email protected]
This version can be pinned in stack with:json-autotype-,8790


Takes a JSON format input, and generates automatic Haskell type declarations.

Parser and printer instances are derived using Aeson.

The program uses union type unification to trim output declarations. The types of same attribute tag and similar attribute set, are automatically unified using recognition by attribute set matching. (This option can be optionally turned off, or a set of unified types may be given explicitly.) Either alternatives is used to assure that all JSON inputs seen in example input file are handled correctly.

I should probably write a short paper to explain the methodology.

Build Status Hackage

Details on official releases are on Hackage


After installing with cabal install json-autotype, you might generate stub code for the parser:

    json-autotype input.json -o MyFormat.hs

Then you might test the parser by running it on an input file:

    runghc MyFormat.hs input.json

If everything is correct, then feel free to inspect the data structure generated automatically for you! The goal of this program is to make it easy for users of big JSON APIs to generate entries from example data.

Occasionally you might find a valid JSON for which json-autotype doesn’t generate a correct parser. You may either edit the resulting file and send it to the author as a test case for future release.

Patches and suggestions are welcome.


The most simple example:


It will produce the module with the following datatypes and TH calls for JSON parser derivations:

    data ColorsArray = ColorsArray {
        colorsArrayHexValue    :: Text,
        colorsArrayColorName :: Text
      } deriving (Show,Eq)

    data TopLevel = TopLevel {
        topLevelColorsArray :: ColorsArray
      } deriving (Show,Eq)

Note that attribute names match the names of JSON dictionary keys.

Another example with ambiguous types:

                "parameterValue":"site API"

It will produce quite intuitive result (plus extra parentheses, and class derivations):

    data Parameter = Parameter {
        parameterParameterValue :: Either Bool (Either Int Text),
        parameterParameterName :: Text

    data TopLevel = TopLevel {
        topLevelParameter :: Parameter

Real-world use case examples are provided in the package source repository.


Changelog  Apr 2015

    * Correctly handling lone option, not yet union with optionality.
      Fixed: #3.  Apr 2015

    * Added typechecking before and after type unification.
    * Added shrink for more informative QuickCheck testing.
    * Tested mostly using GHC 7.10.  Mar 2015

    * Add short versions of command line flags: -o, -d, and -t.  Mar 2015

    * Bump up lens dependency.  Mar 2015

    * Updated tests and build config.  Mar 2015

    * Fixed documentation anchors, and unit test classification for failures.  Mar 2015

    * Relaxed upper bounds for lens 4.8. Mar 2015

    * (Skipped this version number by mistake.)  Dec 2014

    * Relaxed upper bounds for new lens.  Dec 2014

    * Relaxed upper bounds again.  Dec 2014

    * Updated metainfo, relaxed upper bounds for GHC 7.10.  Nov 2014

    * Nicer union type syntax in Data.Aeson.AutoType.Alternative.  Nov 2014

    * To assure proper treatment of unions,
      I make them with Data.Aeson.AutoType.Alternative type instead of Either.  Nov 2014

    * Explicit JSON parser generation to avoid conflicts between Haskell keywords and field names.
    * Renaming of Haskell field names with a prefix of object name (data type.)  Nov 2014

    * GenerateJSONParser may now take multiple input samples to produce single parser.
    * Fixed automated testing for all example files.  Oct 2014

    * Added examples to the package distribution.  Oct 2014

    * Cleaned up package.
    * Changelog in markdown format.

0.2.1  Oct 2014

    * Added option to use it as a filter ('-' is accepted input name.)

0.2.0  Oct 2014

    * First release to Hackage.
    * Handling of proper unions, and most examples.
    * Automatically tested on a wide range of example documents (see
    * Initial documentation in README.md.

0.1.0  July 2014

* First experiments uploaded to GitHub, and discussed to