diff --git a/LICENSE.txt b/LICENSE.txt
new file mode 100644
--- /dev/null
+++ b/LICENSE.txt
@@ -0,0 +1,16 @@
+Copyright (c) 2022 Eric Torreborre <etorreborre@yahoo.com>
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
+documentation files (the "Software"), to deal in the Software without restriction, including without limitation
+the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software,
+and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all copies or substantial portions of
+the Software. Neither the name of specs nor the names of its contributors may be used to endorse or promote
+products derived from this software without specific prior written permission.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
+TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+DEALINGS IN THE SOFTWARE.
diff --git a/Setup.hs b/Setup.hs
new file mode 100644
--- /dev/null
+++ b/Setup.hs
@@ -0,0 +1,4 @@
+import Distribution.Simple
+
+main :: IO ()
+main = defaultMain
diff --git a/registry-hedgehog-aeson.cabal b/registry-hedgehog-aeson.cabal
new file mode 100644
--- /dev/null
+++ b/registry-hedgehog-aeson.cabal
@@ -0,0 +1,139 @@
+cabal-version: 1.12
+
+-- This file has been generated from package.yaml by hpack version 0.34.4.
+--
+-- see: https://github.com/sol/hpack
+
+name:           registry-hedgehog-aeson
+version:        0.1.0.0
+synopsis:       Hedgehog generators for Aeson
+description:    This library provides generators for Aeson values which can be easily customized.
+category:       Test
+maintainer:     etorreborre@yahoo.com
+license:        MIT
+license-file:   LICENSE.txt
+build-type:     Simple
+
+source-repository head
+  type: git
+  location: https://github.com/etorreborre/registry-hedgehog-aeson
+
+library
+  exposed-modules:
+      Data.Registry.Hedgehog.AesonGenerators
+  other-modules:
+      Paths_registry_hedgehog_aeson
+  hs-source-dirs:
+      src
+  default-extensions:
+      BangPatterns
+      DefaultSignatures
+      EmptyCase
+      ExistentialQuantification
+      FlexibleContexts
+      FlexibleInstances
+      FunctionalDependencies
+      GADTs
+      GeneralizedNewtypeDeriving
+      InstanceSigs
+      KindSignatures
+      LambdaCase
+      MultiParamTypeClasses
+      MultiWayIf
+      NamedFieldPuns
+      NoImplicitPrelude
+      OverloadedStrings
+      PatternSynonyms
+      Rank2Types
+      RankNTypes
+      ScopedTypeVariables
+      StandaloneDeriving
+      TupleSections
+      TypeApplications
+      TypeFamilies
+      TypeFamilyDependencies
+      TypeOperators
+  ghc-options: -Wall -Wcompat -Wincomplete-record-updates -fhide-source-paths -fprint-potential-instances -fno-warn-partial-type-signatures -optP-Wno-nonportable-include-path -Wincomplete-uni-patterns
+  build-depends:
+      aeson >=1.0 && <3
+    , base >=4.7 && <5
+    , containers >=0.2 && <1
+    , hedgehog >=1.0 && <2
+    , mmorph ==1.*
+    , multimap ==1.*
+    , protolude ==0.3.*
+    , registry ==0.2.*
+    , scientific ==0.3.*
+    , tasty ==1.*
+    , tasty-discover >=2 && <5
+    , tasty-hedgehog >=1.0 && <2.0
+    , tasty-th >=0.1 && <1
+    , template-haskell >=2.13 && <3.0
+    , text ==1.*
+    , transformers >=0.5 && <2
+    , universum ==1.*
+    , unordered-containers >=0.1 && <1
+    , vector >=0.1 && <1
+  default-language: Haskell2010
+
+test-suite spec
+  type: exitcode-stdio-1.0
+  main-is: test.hs
+  other-modules:
+      AutoDiscoveredSpecs
+      Test.Data.Registry.Hedgehog.AesonGeneratorsSpec
+      Paths_registry_hedgehog_aeson
+  hs-source-dirs:
+      test
+  default-extensions:
+      BangPatterns
+      DefaultSignatures
+      EmptyCase
+      ExistentialQuantification
+      FlexibleContexts
+      FlexibleInstances
+      FunctionalDependencies
+      GADTs
+      GeneralizedNewtypeDeriving
+      InstanceSigs
+      KindSignatures
+      LambdaCase
+      MultiParamTypeClasses
+      MultiWayIf
+      NamedFieldPuns
+      NoImplicitPrelude
+      OverloadedStrings
+      PatternSynonyms
+      Rank2Types
+      RankNTypes
+      ScopedTypeVariables
+      StandaloneDeriving
+      TupleSections
+      TypeApplications
+      TypeFamilies
+      TypeFamilyDependencies
+      TypeOperators
+  ghc-options: -Wall -Wcompat -Wincomplete-record-updates -fhide-source-paths -fprint-potential-instances -fno-warn-partial-type-signatures -optP-Wno-nonportable-include-path -threaded -rtsopts -with-rtsopts=-N -fno-warn-orphans -fno-warn-missing-signatures -fno-warn-incomplete-uni-patterns -fno-warn-type-defaults -optP-Wno-nonportable-include-path
+  build-depends:
+      aeson >=1.0 && <3
+    , base >=4.7 && <5
+    , containers >=0.2 && <1
+    , hedgehog >=1.0 && <2
+    , mmorph ==1.*
+    , multimap ==1.*
+    , protolude ==0.3.*
+    , registry ==0.2.*
+    , registry-hedgehog
+    , registry-hedgehog-aeson
+    , scientific ==0.3.*
+    , tasty ==1.*
+    , tasty-discover >=2 && <5
+    , tasty-hedgehog >=1.0 && <2.0
+    , tasty-th >=0.1 && <1
+    , template-haskell >=2.13 && <3.0
+    , text ==1.*
+    , transformers >=0.5 && <2
+    , universum ==1.*
+    , unordered-containers >=0.1 && <1
+    , vector >=0.1 && <1
+  default-language: Haskell2010
diff --git a/src/Data/Registry/Hedgehog/AesonGenerators.hs b/src/Data/Registry/Hedgehog/AesonGenerators.hs
new file mode 100644
--- /dev/null
+++ b/src/Data/Registry/Hedgehog/AesonGenerators.hs
@@ -0,0 +1,147 @@
+{-# LANGUAGE DataKinds #-}
+{-# LANGUAGE DerivingStrategies #-}
+{-# LANGUAGE MonoLocalBinds #-}
+{-# LANGUAGE PartialTypeSignatures #-}
+{-# OPTIONS_GHC -fno-warn-partial-type-signatures #-}
+
+module Data.Registry.Hedgehog.AesonGenerators where
+
+import Data.Aeson
+import Data.Registry
+import Data.Registry.Internal.Types (Typed)
+import Data.Scientific as Scientific hiding (normalize)
+import Data.Vector as Vector (fromList)
+import Hedgehog as H
+import Hedgehog.Gen as Gen hiding (either)
+import Hedgehog.Range as Range
+import Protolude
+
+-- | Generator for a default JSON value
+genValue :: Gen Value
+genValue = genValueFor simpleGens
+
+-- | Generator for a JSON value with an adjusted set of generators
+--   For example:
+--    - change the recursive depth of the generation: genValueWith (setDepth 5)
+--    - change the number of elements in an array or an object: genValueWith (setFieldsNb 5)
+--    - use a custom text generator: genValueWith (setGen myTextGenerator)
+--    - change the range used for generating numbers: genValueWith (setRange (linear @Int 0 20))
+genValueWith :: (Registry _ _ -> Registry _ _) -> Gen Value
+genValueWith f = genValueFor (f simpleGens)
+
+-- | Specialized generator for a number value
+genNumberValue :: Gen Value
+genNumberValue = unTag <$> make @(Gen (Tag "Number" Value)) simpleGens
+
+-- | Generate a JSON value with a given set of generators to be used when recursing
+genValueFor :: Registry _ _ -> Gen Value
+genValueFor gens =
+  case make @Depth gens of
+    -- if the depth is 0 generate a Value from the `Simple` Value generation
+    0 -> make @(Gen Value) gens
+    -- if the depth is > 0 generate possibly recursive values like arrays and objects
+    _ -> make @(Gen Value) $ recursiveGens (decrementDepth gens)
+
+-- | Set of generators for JSON values including recursive values like arrays and objects
+--   In order to control the recursivity of the Value data type we produce several types
+--   for JSON values using tags:
+--     `Recurse Value` is a generated value to be used when generating an array or an object
+--     `Simple Value` is a generated value that is either: a String, a Number, a Bool, a Null value
+recursiveGens :: Registry _ _ -> Registry _ _
+recursiveGens overrides =
+  normalize $
+    -- generator choosing between generated arrays, objects or simple values
+    gen genRecursiveValue
+      -- generator for objects
+      <: gen genObject
+      -- generator for arras
+      <: gen genArray
+      -- generator for field names (up to 3 by default)
+      <: fun (listOf @Text 1 3)
+      -- generator for the elements of arrays or objects (up to 3 by default)
+      <: fun (listOf @(Tag "Recurse" Value) 1 3)
+      -- generator for a JSON value to be used in an object or an array
+      <: fun (tag <$> genValueFor overrides :: Gen (Tag "Recurse" Value))
+      -- simple, non-recursive, generators
+      <: overrides
+
+-- | Set of generators for non-recursive JSON values
+--   Those value are tagged as `Simple` but we can also extract a `Gen Value` from this list
+simpleGens :: Registry _ _
+simpleGens =
+  gen untagSimpleValue
+    <: gen genSimpleValue
+    <: gen genNumber
+    <: gen genString
+    <: gen genText
+    <: gen genBool
+    <: gen genNull
+    <: gen (linear 0 5 :: Range Int)
+    <: gen (linear (-1000) 1000 :: Range Integer)
+    <: val (Depth 3)
+
+-- * Individual generators
+
+genRecursiveValue :: Tag "Array" Value -> Tag "Object" Value -> Tag "Simple" Value -> Gen Value
+genRecursiveValue arrayValue objectValue simpleValue = Gen.element [unTag arrayValue, unTag objectValue, unTag simpleValue]
+
+untagSimpleValue :: Tag "Simple" Value -> Value
+untagSimpleValue = unTag
+
+genSimpleValue :: Tag "Null" Value -> Tag "Bool" Value -> Tag "Number" Value -> Tag "String" Value -> Gen (Tag "Simple" Value)
+genSimpleValue nullValue boolValue numberValue stringValue =
+  tag <$> Gen.element [unTag nullValue, unTag boolValue, unTag numberValue, unTag stringValue]
+
+genNull :: Gen (Tag "Null" Value)
+genNull = pure (tag Null)
+
+genBool :: Gen (Tag "Bool" Value)
+genBool = tag . Bool <$> Gen.bool
+
+genText :: Range Int -> Gen Text
+genText range = Gen.text range Gen.alphaNum
+
+genString :: Text -> Tag "String" Value
+genString = tag . String
+
+genNumber :: Range Integer -> Gen (Tag "Number" Value)
+genNumber range = fmap tag $ Number <$> (scientific <$> Gen.integral range <*> pure 0)
+
+genArray :: [Tag "Recurse" Value] -> Tag "Array" Value
+genArray = tag . Array . Vector.fromList . fmap unTag
+
+genObject :: [Text] -> [Tag "Recurse" Value] -> Tag "Object" Value
+genObject fields values = tag . object $ zip fields (unTag <$> values)
+
+-- * SUPPORT FUNCTION
+
+-- | Simplification for funTo @Gen when adding a new function to the registry
+gen :: forall a b. (ApplyVariadic Gen a b, Typeable a, Typeable b) => a -> Typed b
+gen = funTo @Gen
+
+-- | set a specific generator on top of the list of generators
+setGen :: (Typeable a) => Gen a -> Registry _ _ -> Registry _ _
+setGen = addFun
+
+-- | set a specific range on top of the list of generators
+setRange :: (Typeable a) => Range a -> Registry _ _ -> Registry _ _
+setRange = addFun
+
+-- | Generate a list of min' to max' elements
+listOf :: forall a. Int -> Int -> Gen a -> Gen [a]
+listOf min' max' = Gen.list (linear min' max')
+
+-- | Simplification for setting a new recursion depth on the registry
+setDepth :: Depth -> Registry _ _ -> Registry _ _
+setDepth d r = normalize $ val d +: r
+
+-- | Decrement the depth of generation during recursion
+decrementDepth :: Registry _ _ -> Registry _ _
+decrementDepth = tweak (\(d :: Depth) -> d - 1)
+
+-- | Simplification for setting the number of fields
+setFieldsNb :: Int -> Registry _ _ -> Registry _ _
+setFieldsNb n r = fun (listOf @Text 1 n) +: r
+
+newtype Depth = Depth {unDepth :: Int}
+  deriving newtype (Eq, Show, Num)
diff --git a/test/AutoDiscoveredSpecs.hs b/test/AutoDiscoveredSpecs.hs
new file mode 100644
--- /dev/null
+++ b/test/AutoDiscoveredSpecs.hs
@@ -0,0 +1,1 @@
+{-# OPTIONS_GHC -F -pgmF tasty-discover -optF --generated-module=AutoDiscoveredSpecs #-}
diff --git a/test/Test/Data/Registry/Hedgehog/AesonGeneratorsSpec.hs b/test/Test/Data/Registry/Hedgehog/AesonGeneratorsSpec.hs
new file mode 100644
--- /dev/null
+++ b/test/Test/Data/Registry/Hedgehog/AesonGeneratorsSpec.hs
@@ -0,0 +1,23 @@
+{-# LANGUAGE DataKinds #-}
+{-# LANGUAGE PartialTypeSignatures #-}
+{-# OPTIONS_GHC -fno-warn-missing-signatures #-}
+{-# OPTIONS_GHC -fno-warn-orphans #-}
+{-# OPTIONS_GHC -fno-warn-partial-type-signatures #-}
+
+module Test.Data.Registry.Hedgehog.AesonGeneratorsSpec where
+
+import Protolude
+import Test.Tasty.Hedgehogx
+
+-- | Sanity check
+test_json_simple_values = prop "generate simple json values" $ do
+  -- uncomment to display the generated values
+  -- values <- forAll (genValueWith (setDepth 0))
+  -- collect values
+  success
+
+test_json_complex_values = prop "generate complex json values" $ do
+  -- uncomment to display the generated values
+  -- values <- forAll (genValueWith (setDepth 2))
+  -- collect values
+  success
diff --git a/test/test.hs b/test/test.hs
new file mode 100644
--- /dev/null
+++ b/test/test.hs
@@ -0,0 +1,5 @@
+import AutoDiscoveredSpecs (tests)
+import Protolude
+import Test.Tasty.Hedgehogx
+
+main = tests >>= defaultMain . groupByModuleName
