JSON to Haskell Converter Online

Generate Haskell data declarations from any JSON payload — deriving Show, Generic, plus FromJSON and ToJSON instances for Aeson. 100% in your browser.

What is a JSON to Haskell converter?

A JSON to Haskell converter reads a JSON sample and emits a Haskell data record that derives Generic and gets FromJSON / ToJSON instances for free via Aeson. The output drops straight into a Yesod, Servant, or Hasql-backed project and decodes with Data.Aeson.eitherDecode at runtime.

Hand-writing Haskell data records and Aeson instances for a 100-field API payload is slow, especially for nested objects — every nested type needs its own data plus matching instances. OpenFormatter walks the JSON tree once, generates idiomatic Haskell, and runs entirely in your browser so internal API responses never leave your machine.

How to generate Haskell from JSON — 4 steps

  1. Paste a representative JSON response. Type inference reads the first observed value of each field — booleans must be true/false, numbers must be unquoted.
  2. Click Convert. The tool emits a Generated module with data declarations, deriving Show + Generic, and empty FromJSON/ToJSON instances.
  3. Copy and paste into your project. The module pragma {-# LANGUAGE DeriveGeneric #-} and Aeson imports are included.
  4. Decode at runtime. Data.Aeson.eitherDecode bytes :: Either String Root — pattern-match on Left/Right and propagate errors via your monad.

JSON to Haskell example

Sample JSON

{
  "id": 42,
  "name": "Ada Lovelace",
  "active": true
}

Generated Haskell

{-# LANGUAGE DeriveGeneric #-}

module Generated where

import Data.Aeson
import GHC.Generics

data Root = Root
  { rootId :: Int
  , rootName :: String
  , rootActive :: Bool
  } deriving (Show, Generic)

instance FromJSON Root
instance ToJSON Root

Aeson Generic deriving

Empty FromJSON / ToJSON instances backed by GHC.Generics — zero boilerplate, all the type safety, pure compile-time encoding.

Nested types

Every nested JSON object becomes its own data declaration with its own Aeson instances. Field-name prefixing avoids selector clashes.

Client-Side Only

JSON is parsed in JavaScript inside the browser. Internal API responses, tokens, or PII never reach a server.

Common use cases

  • check_circleBuilding a Servant API server where request and response bodies need typed data records
  • check_circleDecoding webhook payloads (Stripe, GitHub, Slack) in a Haskell handler with Aeson
  • check_circleModelling Hasql or persistent database query result rows from a Postgres JSON column
  • check_circleGenerating types for a Yesod application that exposes a REST or GraphQL API
  • check_circleProducing fixtures for QuickCheck property tests around an Aeson encode/decode round-trip
  • check_circleModelling Kafka or RabbitMQ event payloads consumed by a Haskell stream processor
  • check_circleBuilding CLI tools that parse JSON output from kubectl, terraform, or aws-cli
  • check_circleGenerating typed config records for an application loaded from config.json at startup

Why client-side generation matters

The JSON you paste often contains real customer data, OAuth tokens, signed URLs, or internal field names you do not want indexed by a third-party converter. OpenFormatter generates the Haskell entirely in JavaScript on your device — open the Network tab in DevTools and you will see zero requests when you click Convert. Safe for enterprise use, safe behind a corporate proxy, safe when the API contract is itself confidential.

Need other functional-language tooling?

Generate Elm records and decoders, Rust serde structs, or browse other JSON converters — all browser-side.

Frequently Asked Questions

What is Aeson?

Aeson is the de-facto JSON library for Haskell — fast, well-typed, and supports automatic deriving of FromJSON and ToJSON instances from a Generic representation. Most Haskell production codebases (Yesod, Servant, Hasql-based services) depend on Aeson directly or transitively. The package is maintained on Hackage as aeson.

How does FromJSON / ToJSON work?

FromJSON is a typeclass with a parseJSON method that converts a Value (Aeson’s parsed JSON tree) into your data type — typically returning Either String YourType. ToJSON does the reverse with toJSON :: YourType -> Value. With deriving Generic, you can write instance FromJSON YourType (an empty instance) and Aeson uses GHC.Generics to derive the implementation at compile time.

How does Generic deriving work?

GHC.Generics provides a structural representation of a Haskell type at compile time. Aeson’s default FromJSON / ToJSON implementations are written in terms of that Generic representation, so any data type that derives Generic gets free JSON instances by writing instance FromJSON Foo and instance ToJSON Foo (no method bodies required). The {-# LANGUAGE DeriveGeneric #-} pragma enables the syntax.

How are field names mapped to JSON keys?

By default Aeson uses the Haskell field name verbatim as the JSON key. Because Haskell record field selectors are top-level functions, the generator prefixes them with the lowercased type name to avoid name clashes (e.g. rootId instead of id). To map back to the bare key id at JSON time, customize the encoding with genericParseJSON defaultOptions{fieldLabelModifier = drop 4} or by writing custom Aeson Options.

How are nested JSON objects modelled?

Each nested JSON object becomes its own data declaration with its own FromJSON/ToJSON instances. The parent type references the child type by name. Order is emitted so that nested types appear before parents reference them (Haskell does not strictly require this, but it improves readability).

How are JSON arrays handled?

A JSON array becomes [T] (Haskell list of T) where T is inferred from the first element. Arrays of strings become [String]; arrays of objects become [ChildType]. For arrays of mixed types use [Value] (Aeson’s untyped JSON value) and pattern-match at use site.

Is the JSON uploaded to your servers?

No. Conversion runs entirely in your browser via JavaScript. Open DevTools → Network and click Convert — no requests are made. Pasting JSON containing tokens or proprietary data never leaves your machine.

How do I parse a JSON string at runtime?

Use Data.Aeson.eitherDecode :: ByteString -> Either String Root from a lazy ByteString. For strict ByteString use eitherDecodeStrict. Pattern-match on Left err / Right value and propagate errors via your monad. The generator output works with all variants of the Aeson decode family.

JSON to Haskell Converter Online — Aeson Data