Type driven generic aeson instance customisation

Version on this page:0.2.7
LTS Haskell 22.29:0.2.9@rev:1
Stackage Nightly 2024-07-15:0.2.9@rev:1
Latest on Hackage:0.2.9@rev:1

See all snapshots deriving-aeson appears in

BSD-3-Clause licensed by Fumiaki Kinoshita
Maintained by [email protected]
This version can be pinned in stack with:deriving-aeson-0.2.7@sha256:4565961c5c1b5c3c6d696d89a90aea3185a5ba858d4a481315d9b4310689ccf0,1277

Module documentation for 0.2.7

Depends on 2 packages(full list with versions):


Hackage Haskell CI Discord


This package provides a newtype wrapper where you can customise aeson’s generic methods using a type-level interface, which synergises well with DerivingVia.

{-# LANGUAGE DerivingVia, DataKinds, DeriveGeneric #-}
import Data.Aeson
import Deriving.Aeson
import qualified Data.ByteString.Lazy.Char8 as BL

data User = User
  { userId :: Int
  , userName :: String
  , userAPIToken :: Maybe String
  } deriving Generic
  deriving (FromJSON, ToJSON)
  via CustomJSON '[OmitNothingFields, FieldLabelModifier '[StripPrefix "user", CamelToSnake]] User

testData :: [User]
testData = [User 42 "Alice" Nothing, User 43 "Bob" (Just "xyz")]

main = BL.putStrLn $ encode testData
-- [{"name":"Alice","id":42},{"api_token":"xyz","name":"Bob","id":43}]

Deriving.Aeson.Stock contains some aliases for even less boilerplates.

  • Prefixed str = CustomJSON '[FieldLabelModifier (StripPrefix str)]
  • PrefixedSnake str = CustomJSON '[FieldLabelModifier (StripPrefix str, CamelToSnake)]
  • Snake = CustomJSON '[FieldLabelModifier '[StripPrefix str, CamelToSnake]]
  • Vanilla = CustomJSON '[]

How it works

The wrapper type has a phantom type parameter t, a type-level builder of an Option. Type-level primitives are reduced to one Option by the AesonOptions class.

newtype CustomJSON t a = CustomJSON { unCustomJSON :: a }

class AesonOptions xs where
  aesonOptions :: Options

instance AesonOptions xs => AesonOptions (OmitNothingFields ': xs) where
  aesonOptions = (aesonOptions @xs) { omitNothingFields = True }


You can use any (static) function for name modification by adding an instance of StringModifier.

data ToLower
instance StringModifier ToLower where
  getStringModifier "" = ""
  getStringModifier (c : xs) = toLower c : xs

Previous studies


Revision history for deriving-aeson


  • Added a StringModifier instance to a list of types
  • Added Rename :: Symbol -> Symbol -> Type


  • Added StringModifier instances to 3 and 4-tuples
  • Fixed the bug making SumTwoElemArray point ObjectWithSingleField


  • Added a generic CamelTo constructor


  • Added RejectUnknownFields


  • Fixed a bug in SumTaggedObject


  • Added UnwrapUnaryRecords


  • Remove redundant type variables from Sum*


  • Added Sum* for changing the encoding of variants
  • Added Vanilla = CustomJSON '[]
  • Renamed ContructorTagModifier to ConstructorTagModifier
  • Added toEncoding implementation to CustomJSON


  • Reexported CustomJSON(..) from Deriving.Aeson.Stock


  • Added Deriving.Aeson.Stock

0 – 2020-02-26

  • First version. Released on an unsuspecting world.