diff --git a/LICENSE.md b/LICENSE.md
new file mode 100644
--- /dev/null
+++ b/LICENSE.md
@@ -0,0 +1,5 @@
+# Sydtest License
+
+Copyright (c) 2021 Tom Sydney Kerckhove
+
+See the Sydtest License at https://github.com/NorfairKing/sydtest/blob/master/sydtest/LICENSE.md for the full license text.
diff --git a/src/Test/Syd/Aeson.hs b/src/Test/Syd/Aeson.hs
new file mode 100644
--- /dev/null
+++ b/src/Test/Syd/Aeson.hs
@@ -0,0 +1,93 @@
+{-# LANGUAGE DataKinds #-}
+{-# LANGUAGE OverloadedStrings #-}
+
+module Test.Syd.Aeson
+  ( -- * Golden tests
+    goldenJSONFile,
+    pureGoldenJSONFile,
+    goldenJSONValueFile,
+    pureGoldenJSONValueFile,
+  )
+where
+
+import Control.Monad
+import Data.Aeson as JSON
+import Data.Aeson.Encode.Pretty as JSON
+import qualified Data.ByteString as SB
+import qualified Data.ByteString.Lazy as LB
+import Data.Text.Encoding as TE
+import Path
+import Path.IO
+import Test.Syd
+
+-- | Test that the produced 'JSON.Value' is the same as what we find in the given golden file.
+--
+-- This function shows a diff based on the encoding of the values.
+goldenJSONFile :: FilePath -> IO JSON.Value -> GoldenTest JSON.Value
+goldenJSONFile fp produceActualValue =
+  GoldenTest
+    { goldenTestRead = do
+        p <- resolveFile' fp
+        mContents <- forgivingAbsence $ SB.readFile (fromAbsFile p)
+        forM mContents $ \contents ->
+          case JSON.eitherDecode (LB.fromStrict contents) of
+            Left err -> expectationFailure err
+            Right r -> pure r,
+      goldenTestProduce = produceActualValue,
+      goldenTestWrite = \v -> do
+        p <- resolveFile' fp
+        ensureDir (parent p)
+        SB.writeFile (fromAbsFile p) $ LB.toStrict $ JSON.encodePretty v,
+      goldenTestCompare = \actual expected ->
+        if actual == expected
+          then Nothing
+          else
+            Just
+              ( Context
+                  ( textsNotEqualButShouldHaveBeenEqual
+                      (TE.decodeUtf8 (LB.toStrict (JSON.encodePretty actual)))
+                      (TE.decodeUtf8 (LB.toStrict (JSON.encodePretty expected)))
+                  )
+                  (goldenContext fp)
+              )
+    }
+
+-- | Test that the given 'JSON.Value' is the same as what we find in the given golden file.
+--
+-- This function shows a diff based on the encoding of the values.
+pureGoldenJSONFile :: FilePath -> JSON.Value -> GoldenTest JSON.Value
+pureGoldenJSONFile fp actualValue = goldenJSONFile fp $ pure actualValue
+
+-- | Test that the produced 'JSON.Value' is the same as what we find in the given golden file.
+--
+-- This test also tests that the previously written 'toJSON'-ed version of the given value is still parseable as to same value.
+--
+-- This function shows a diff based on the pretty 'Show'ing of the values.
+goldenJSONValueFile :: (Show a, Eq a, FromJSON a, ToJSON a) => FilePath -> IO a -> GoldenTest a
+goldenJSONValueFile fp produceActualValue =
+  GoldenTest
+    { goldenTestRead = do
+        p <- resolveFile' fp
+        mContents <- forgivingAbsence $ SB.readFile (fromAbsFile p)
+        forM mContents $ \contents ->
+          case JSON.eitherDecode (LB.fromStrict contents) of
+            Left err -> expectationFailure err
+            Right r -> pure r,
+      goldenTestProduce = produceActualValue,
+      goldenTestWrite = \v -> do
+        p <- resolveFile' fp
+        ensureDir (parent p)
+        SB.writeFile (fromAbsFile p) $ LB.toStrict $ JSON.encodePretty v,
+      goldenTestCompare = \actual expected ->
+        if actual == expected
+          then Nothing
+          else Just (Context (stringsNotEqualButShouldHaveBeenEqual (ppShow actual) (ppShow expected)) (goldenContext fp))
+    }
+
+-- | Test that the given 'JSON.Value' is the same as what we find in the given golden file.
+--
+-- This test also tests that the previously written 'toJSON'-ed version of the given value is still parseable as to same value.
+--
+-- This function shows a diff based on the pretty 'Show'ing of the values.
+pureGoldenJSONValueFile :: (Show a, Eq a, FromJSON a, ToJSON a) => FilePath -> a -> GoldenTest a
+pureGoldenJSONValueFile fp actualValue = goldenJSONValueFile fp $ pure actualValue
diff --git a/sydtest-aeson.cabal b/sydtest-aeson.cabal
new file mode 100644
--- /dev/null
+++ b/sydtest-aeson.cabal
@@ -0,0 +1,61 @@
+cabal-version: 1.12
+
+-- This file has been generated from package.yaml by hpack version 0.34.4.
+--
+-- see: https://github.com/sol/hpack
+--
+-- hash: 2fe968a3a35d7b58c088bbfec8b58386928f7006a3424e650e765781459c162a
+
+name:           sydtest-aeson
+version:        0.0.0.0
+synopsis:       An aeson companion library for sydtest
+category:       Testing
+homepage:       https://github.com/NorfairKing/sydtest#readme
+bug-reports:    https://github.com/NorfairKing/sydtest/issues
+author:         Tom Sydney Kerckhove
+maintainer:     syd@cs-syd.eu
+copyright:      Copyright (c) 2021 Tom Sydney Kerckhove
+license:        OtherLicense
+license-file:   LICENSE.md
+build-type:     Simple
+
+source-repository head
+  type: git
+  location: https://github.com/NorfairKing/sydtest
+
+library
+  exposed-modules:
+      Test.Syd.Aeson
+  other-modules:
+      Paths_sydtest_aeson
+  hs-source-dirs:
+      src
+  build-depends:
+      aeson
+    , aeson-pretty
+    , base >=4.7 && <5
+    , bytestring
+    , path
+    , path-io
+    , sydtest
+    , text
+  default-language: Haskell2010
+
+test-suite sydtest-aeson-test
+  type: exitcode-stdio-1.0
+  main-is: Spec.hs
+  other-modules:
+      Test.Syd.AesonSpec
+      Paths_sydtest_aeson
+  hs-source-dirs:
+      test
+  ghc-options: -threaded -rtsopts -with-rtsopts=-N -Wall
+  build-tool-depends:
+      sydtest-discover:sydtest-discover
+  build-depends:
+      aeson
+    , base >=4.7 && <5
+    , sydtest
+    , sydtest-aeson
+    , text
+  default-language: Haskell2010
diff --git a/test/Spec.hs b/test/Spec.hs
new file mode 100644
--- /dev/null
+++ b/test/Spec.hs
@@ -0,0 +1,1 @@
+{-# OPTIONS_GHC -F -pgmF sydtest-discover #-}
diff --git a/test/Test/Syd/AesonSpec.hs b/test/Test/Syd/AesonSpec.hs
new file mode 100644
--- /dev/null
+++ b/test/Test/Syd/AesonSpec.hs
@@ -0,0 +1,33 @@
+{-# LANGUAGE OverloadedStrings #-}
+
+module Test.Syd.AesonSpec (spec) where
+
+import Data.Aeson as JSON
+import Data.Text (Text)
+import Test.Syd
+import Test.Syd.Aeson
+
+spec :: Spec
+spec = do
+  describe "pureGoldenJSONFile" $
+    it "outputs this example the same as before" $
+      pureGoldenJSONFile
+        "test_resources/pure-example.json"
+        $ JSON.object
+          ["hello" .= ("world" :: Text), "a" .= (1 :: Int), "b" .= True]
+  describe "goldenJSONFile" $
+    it "outputs this example the same as before" $
+      goldenJSONFile
+        "test_resources/example.json"
+        $ pure $ JSON.object ["hello" .= ("world" :: Text), "a" .= (1 :: Int), "b" .= True]
+  describe "pureGoldenJSONValueFile" $
+    it "outputs this example the same as before" $
+      pureGoldenJSONValueFile
+        "test_resources/pure-example.json"
+        $ JSON.object
+          ["hello" .= ("world" :: Text), "a" .= (1 :: Int), "b" .= True]
+  describe "goldenJSONValueFile" $
+    it "outputs this example the same as before" $
+      goldenJSONValueFile
+        "test_resources/example.json"
+        $ pure $ JSON.object ["hello" .= ("world" :: Text), "a" .= (1 :: Int), "b" .= True]
