diff --git a/CHANGELOG.md b/CHANGELOG.md
new file mode 100644
--- /dev/null
+++ b/CHANGELOG.md
@@ -0,0 +1,7 @@
+# Changes
+
+## Version 0.1.0.0
+
+_2024-12-17_
+
+- Introducing `GoldenVsShow`, `GoldenVsString`, `GoldenVsToJSON`, `GoldenVsToYAML`
diff --git a/LICENSE b/LICENSE
new file mode 100644
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,29 @@
+Copyright (C) 2024 Bellroy Pty Ltd
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+
+1. Redistributions of source code must retain the above copyright
+   notice, this list of conditions and the following disclaimer.
+
+2. Redistributions in binary form must reproduce the above copyright
+   notice, this list of conditions and the following disclaimer in the
+   documentation and/or other materials provided with the
+   distribution.
+
+3. Neither the name of the copyright holder nor the names of its
+   contributors may be used to endorse or promote products derived
+   from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/README.md b/README.md
new file mode 100644
--- /dev/null
+++ b/README.md
@@ -0,0 +1,8 @@
+# tasty-golden-extra
+
+A library providing additional golden test helpers for the
+@tasty-golden@ package. These helpers are useful for testing
+the output of functions that return textual output and instances of @Show@,
+@ToJSON@ or @ToYAML@.
+
+To find out what's new, read the [change log](https://github.com/bellroy/tasty-golden-extra/blob/master/CHANGELOG.md).
diff --git a/src/Test/Tasty/Golden/Extra/GoldenVsShow.hs b/src/Test/Tasty/Golden/Extra/GoldenVsShow.hs
new file mode 100644
--- /dev/null
+++ b/src/Test/Tasty/Golden/Extra/GoldenVsShow.hs
@@ -0,0 +1,76 @@
+{-# LANGUAGE ExistentialQuantification #-}
+
+-- |
+--
+-- Module      : Test.Tasty.Golden.Extra.GoldenVsShow
+-- Copyright   : (C) 2024 Bellroy Pty Ltd
+-- License     : BSD-3-Clause
+-- Maintainer  : Bellroy Tech Team <haskell@bellroy.com>
+-- Stability   : experimental
+--
+-- These helpers are useful for creating golden tests for @Show@ instances.
+module Test.Tasty.Golden.Extra.GoldenVsShow
+  ( goldenVsShow,
+    GoldenVsShow (..),
+  )
+where
+
+import qualified Data.Text.Lazy as Text
+import Data.Text.Lazy.Encoding (encodeUtf8)
+import Test.Tasty (TestName, TestTree)
+import qualified Test.Tasty.Discover as Discover
+import Test.Tasty.Golden
+import Text.Show.Pretty (ppShow)
+
+-- | Tasty-discoverable type for creating golden tests for @Show@ instances.
+--
+-- Example use:
+--
+-- @
+--  import MySchemasWithShowAndToJSONInstances.Person (Person)
+--  import qualified Data.Aeson as Aeson
+--  import System.FilePath ((\</\>))
+--  import Test.Tasty.Golden.Extra.GoldenVsShow (GoldenVsShow (..))
+--
+--  tasty_GoldenVsShow :: GoldenVsShow
+--  tasty_GoldenVsShow =
+--    GoldenVsShow (goldenFilesPath \</\> "Person.golden.txt") $
+--      Aeson.eitherDecodeFileStrict @Person (goldenFilesPath \</\> "Person.json")
+-- @
+data GoldenVsShow = forall a. (Show a) => GoldenVsShow FilePath (IO a)
+
+instance Discover.Tasty GoldenVsShow where
+  tasty info (GoldenVsShow ref act) =
+    pure $ goldenVsShow (Discover.nameOf info) ref act
+
+-- | Helper function for creating a @TestTree@ for @Show@ golden tests.
+-- Use when you want to test @Show@ instances against a golden example on disk.
+--
+-- Example use:
+--
+-- @
+--  import MySchemasWithShowAndShowInstances.Person (Person)
+--  import qualified Data.Aeson as Aeson
+--  import System.FilePath ((\</\>))
+--  import Test.Tasty.Golden.Extra.GoldenVsShow (goldenVsShow)
+--
+--  test_Show :: TestTree
+--  test_Show = do
+--    let inputFile = goldenFilesPath \</\> "Person.json"
+--    goldenVsShow
+--      "Test Show instance for Person"
+--      (goldenFilesPath \</\> "Person.golden.txt")
+--      (Aeson.decodeFileStrict' @Person inputFile)
+-- @
+goldenVsShow ::
+  (Show a) =>
+  -- | test name
+  TestName ->
+  -- | path to the «golden» file (the file that contains correct output)
+  FilePath ->
+  -- | action that returns an instance of the type whose instance is being tested
+  IO a ->
+  -- | the test verifies that the returned string is the same as the golden file contents
+  TestTree
+goldenVsShow name ref =
+  goldenVsString name ref . fmap (encodeUtf8 . Text.pack . ppShow)
diff --git a/src/Test/Tasty/Golden/Extra/GoldenVsString.hs b/src/Test/Tasty/Golden/Extra/GoldenVsString.hs
new file mode 100644
--- /dev/null
+++ b/src/Test/Tasty/Golden/Extra/GoldenVsString.hs
@@ -0,0 +1,41 @@
+-- |
+--
+-- Module      : Test.Tasty.Golden.Extra.GoldenVsString
+-- Copyright   : (C) 2024 Bellroy Pty Ltd
+-- License     : BSD-3-Clause
+-- Maintainer  : Bellroy Tech Team <haskell@bellroy.com>
+-- Stability   : experimental
+--
+-- These helpers are useful for creating golden tests for functions that
+-- produce textual output.
+module Test.Tasty.Golden.Extra.GoldenVsString
+  ( GoldenVsString (..),
+    goldenVsString,
+  )
+where
+
+import Data.ByteString.Lazy (ByteString)
+import qualified Test.Tasty.Discover as Discover
+import Test.Tasty.Golden
+
+-- | Tasty-discoverable type for creating golden tests for functions that produce
+-- textual output.
+--
+-- Example use:
+--
+-- @
+--  import MySchemasWithShowAndToJSONInstances.Person (convertToCSVText)
+--  import qualified Data.Aeson as Aeson
+--  import System.FilePath ((\</\>))
+--  import Test.Tasty.Golden.Extra.GoldenVsString (GoldenVsString (..))
+--
+--  tasty_FromJSON_ToJSON :: GoldenVsString
+--  tasty_FromJSON_ToJSON =
+--    GoldenVsString (goldenFilesPath \</\> "Person.golden.csv") $
+--      maybe "Error" convertToCSVText <$>
+--        Aeson.decodeFileStrict' (goldenFilesPath \</\> "Person.json")
+-- @
+data GoldenVsString = GoldenVsString FilePath (IO ByteString)
+
+instance Discover.Tasty GoldenVsString where
+  tasty info (GoldenVsString ref act) = pure $ goldenVsString (Discover.nameOf info) ref act
diff --git a/src/Test/Tasty/Golden/Extra/GoldenVsToJSON.hs b/src/Test/Tasty/Golden/Extra/GoldenVsToJSON.hs
new file mode 100644
--- /dev/null
+++ b/src/Test/Tasty/Golden/Extra/GoldenVsToJSON.hs
@@ -0,0 +1,85 @@
+{-# LANGUAGE ExistentialQuantification #-}
+
+-- |
+--
+-- Module      : Test.Tasty.Golden.Extra.GoldenVsToJSON
+-- Copyright   : (C) 2024 Bellroy Pty Ltd
+-- License     : BSD-3-Clause
+-- Maintainer  : Bellroy Tech Team <haskell@bellroy.com>
+-- Stability   : experimental
+--
+-- These helpers are useful for creating golden tests for @ToJSON@ instances.
+module Test.Tasty.Golden.Extra.GoldenVsToJSON
+  ( GoldenVsToJSON (..),
+    goldenVsToJson,
+  )
+where
+
+import qualified Data.Aeson as Aeson
+import Data.Aeson.Encode.Pretty (encodePretty)
+import qualified Data.ByteString.Lazy as BL
+import Test.Tasty (TestName, TestTree)
+import qualified Test.Tasty.Discover as Discover
+import Test.Tasty.Golden.Advanced (goldenTest)
+import Test.Tasty.Golden.Extra.Internal (checkJsonDifference, maybeDifference)
+
+-- | Tasty-discoverable type for creating golden tests for @ToJSON@ instances.
+--
+-- Example use:
+--
+-- @
+--  import MySchemasWithToJSONInstances.Person (Person)
+--  import qualified Data.Aeson as Aeson
+--  import System.FilePath ((\</\>))
+--  import Test.Tasty.Golden.Extra.GoldenVsToJSON (GoldenVsToJSON (..))
+--
+--  tasty_FromJSON_ToJSON :: GoldenVsToJSON
+--  tasty_FromJSON_ToJSON =
+--    GoldenVsToJSON (goldenFilesPath \</\> "Person.golden.json") $
+--      Aeson.eitherDecodeFileStrict @Person (goldenFilesPath \</\> "Person.json")
+-- @
+data GoldenVsToJSON = forall a. (Aeson.ToJSON a) => GoldenVsToJSON FilePath (IO a)
+
+instance Discover.Tasty GoldenVsToJSON where
+  tasty info (GoldenVsToJSON ref act) = pure $ goldenVsToJson (Discover.nameOf info) ref act
+
+-- | Helper function for creating a @TestTree@ for @ToJSON@ golden tests.
+-- Use when you want to test @ToJSON@ instances against a golden example on disk.
+--
+-- Example use:
+--
+-- @
+--  import MySchemasWithToJSONInstances.Person (Person)
+--  import qualified Data.Aeson as Aeson
+--  import System.FilePath ((\</\>))
+--  import Test.Tasty.Golden.Extra.GoldenVsToJSON (goldenVsToJSON)
+--
+--  test_ToJSON :: TestTree
+--  test_ToJSON = do
+--    let inputFile = goldenFilesPath \</\> "Person.json"
+--    goldenVsToJSON
+--      "Test ToJSON instance for Person"
+--      (goldenFilesPath \</\> "Person.golden.json")
+--      (Aeson.decodeFileStrict' @Person inputFile)
+-- @
+goldenVsToJson ::
+  forall a.
+  (Aeson.ToJSON a) =>
+  -- | test name
+  TestName ->
+  -- | path to the «golden» file (the file that contains correct output)
+  FilePath ->
+  -- | action that returns an instance of the type whose instance is being tested
+  IO a ->
+  -- | the test verifies that the returned string is the same as the golden file contents
+  TestTree
+goldenVsToJson name fp act =
+  goldenTest
+    name
+    (Aeson.decodeFileStrict fp >>= orFailTest ("Couldn't decode golden JSON file:" <> fp))
+    (Aeson.toJSON <$> act)
+    (\a b -> pure . maybeDifference $ checkJsonDifference a b)
+    (BL.writeFile fp . encodePretty)
+
+orFailTest :: String -> Maybe a -> IO a
+orFailTest msg = maybe (error msg) pure
diff --git a/src/Test/Tasty/Golden/Extra/GoldenVsToYAML.hs b/src/Test/Tasty/Golden/Extra/GoldenVsToYAML.hs
new file mode 100644
--- /dev/null
+++ b/src/Test/Tasty/Golden/Extra/GoldenVsToYAML.hs
@@ -0,0 +1,98 @@
+{-# LANGUAGE AllowAmbiguousTypes #-}
+{-# LANGUAGE ExistentialQuantification #-}
+{-# LANGUAGE OverloadedStrings #-}
+{-# LANGUAGE RankNTypes #-}
+
+-- |
+--
+-- Module      : Test.Tasty.Golden.Extra.GoldenVsToYAML
+-- Copyright   : (C) 2024 Bellroy Pty Ltd
+-- License     : BSD-3-Clause
+-- Maintainer  : Bellroy Tech Team <haskell@bellroy.com>
+-- Stability   : experimental
+--
+-- These helpers are useful for creating golden tests for @ToJSON@ instances,
+-- that you want to convert to YAML using the @Data.Yaml@ package.
+module Test.Tasty.Golden.Extra.GoldenVsToYAML
+  ( goldenVsToYaml,
+    GoldenVsToYAML (..),
+  )
+where
+
+import Data.Aeson
+import qualified Data.Aeson as Aeson
+import qualified Data.ByteString as BL
+import qualified Data.Yaml as Yaml
+import Test.Tasty
+import qualified Test.Tasty.Discover as Discover
+import Test.Tasty.Golden.Advanced (goldenTest)
+import Test.Tasty.Golden.Extra.Internal (checkJsonDifference, maybeDifference)
+
+-- | Tasty-discoverable type for creating golden tests for @ToJSON@ instances,
+-- that you want to convert to YAML using the @Data.Yaml@ package.
+--
+-- Example use:
+--
+-- @
+--  import MySchemasWithToJSONInstances.Person (Person)
+--  import qualified Data.Aeson as Aeson
+--  import System.FilePath ((\</\>))
+--  import Test.Tasty.Golden.Extra.GoldenVsToYAML (GoldenVsToYAML (..))
+--
+--  tasty_FromJSON_ToYAML :: GoldenVsToYAML
+--  tasty_FromJSON_ToYAML =
+--    GoldenVsToYAML (goldenFilesPath \</\> "Person.golden.yaml") $
+--      Aeson.eitherDecodeFileStrict @Person (goldenFilesPath \</\> "Person.json")
+-- @
+data GoldenVsToYAML = forall a. (Aeson.ToJSON a) => GoldenVsToYAML FilePath (IO a)
+
+instance Discover.Tasty GoldenVsToYAML where
+  tasty info (GoldenVsToYAML ref act) = pure $ goldenVsToYaml (Discover.nameOf info) ref act
+
+-- | Helper function for creating a @TestTree@ for @ToJSON@-to-YAML golden tests.
+-- Use when you want to test @ToJSON@ instances against a golden example of YAML
+-- on disk.
+--
+-- Example use:
+--
+-- @
+--  import MySchemasWithToJSONInstances.Person (Person)
+--  import qualified Data.Aeson as Aeson
+--  import System.FilePath ((\</\>))
+--  import Test.Tasty.Golden.Extra.GoldenVsToYAML (goldenVsToYAML)
+--
+--  test_ToYAML :: TestTree
+--  test_ToYAML = do
+--    let inputFile = goldenFilesPath \</\> "Person.yaml"
+--    goldenVsToYAML
+--      "Test YAML serialization for Person"
+--      (goldenFilesPath \</\> "Person.golden.yaml")
+--      (Aeson.decodeFileStrict' @Person inputFile)
+-- @
+goldenVsToYaml ::
+  forall a.
+  (ToJSON a) =>
+  -- | test name
+  TestName ->
+  -- | path to the «golden» file (the file that contains correct output)
+  FilePath ->
+  -- | action that returns an instance of the type whose instance is being tested
+  IO a ->
+  -- | the test verifies that the returned string is the same as the golden file contents
+  TestTree
+goldenVsToYaml name fp act =
+  goldenTest
+    name
+    (Yaml.decodeFileEither fp >>= orFailTest fp)
+    (Aeson.toJSON <$> act)
+    (\a b -> pure . maybeDifference $ checkJsonDifference a b)
+    (BL.writeFile fp . Yaml.encode)
+
+orFailTest :: FilePath -> Either Yaml.ParseException a -> IO a
+orFailTest fp =
+  either
+    ( fail
+        . (\t -> mconcat ["Failed to decode file ", fp, "\n", t])
+        . Yaml.prettyPrintParseException
+    )
+    pure
diff --git a/src/Test/Tasty/Golden/Extra/Internal.hs b/src/Test/Tasty/Golden/Extra/Internal.hs
new file mode 100644
--- /dev/null
+++ b/src/Test/Tasty/Golden/Extra/Internal.hs
@@ -0,0 +1,45 @@
+-- |
+--
+-- Module      : Test.Tasty.Golden.Extra.Internal
+-- Copyright   : (C) 2024 Bellroy Pty Ltd
+-- License     : BSD-3-Clause
+-- Maintainer  : Bellroy Tech Team <haskell@bellroy.com>
+-- Stability   : experimental
+--
+-- Common types and functions  used by the other modules in `tasty-golden-extra`.
+module Test.Tasty.Golden.Extra.Internal
+  ( checkJsonDifference,
+    maybeDifference,
+    JsonDifference (..),
+  )
+where
+
+import qualified Data.Aeson as Aeson
+import Data.Aeson.Diff (diff)
+import Data.Aeson.Patch (patchOperations)
+import qualified Data.Text.Lazy as TL
+import Text.Pretty.Simple (pShowNoColor)
+
+-- | Represents the result of comparing two JSON values - either the JSON is
+-- identical, or there are differences and you are given an error message
+-- containing the differences.
+data JsonDifference
+  = JsonIdentical
+  | JsonDifferent String
+
+-- | Convert a `JsonDifference` to a `Maybe String` containing the error message.
+maybeDifference :: JsonDifference -> Maybe String
+maybeDifference JsonIdentical = Nothing
+maybeDifference (JsonDifferent diffString) = Just diffString
+
+-- | Compare two JSON values and return a `JsonDifference` representing the result.
+checkJsonDifference ::
+  Aeson.Value ->
+  Aeson.Value ->
+  JsonDifference
+checkJsonDifference goldenJson actualJson =
+  case patchOperations $ diff goldenJson actualJson of
+    [] -> JsonIdentical
+    ds ->
+      JsonDifferent $
+        "Files contain different JSON values:\n" <> TL.unpack (pShowNoColor ds)
diff --git a/tasty-golden-extra.cabal b/tasty-golden-extra.cabal
new file mode 100644
--- /dev/null
+++ b/tasty-golden-extra.cabal
@@ -0,0 +1,71 @@
+cabal-version:      3.0
+name:               tasty-golden-extra
+version:            0.1.0.0
+license:            BSD-3-Clause
+license-file:       LICENSE
+category:           Testing
+homepage:
+  https://github.com/bellroy/tasty-golden-extra
+
+bug-reports:        https://github.com/bellroy/tasty-golden-extra/issues
+author:             Bellroy
+maintainer:         geeks@bellroy.com
+build-type:         Simple
+synopsis:           Additional golden test helpers for the tasty-golden package
+description:
+  A library providing additional golden test helpers for the
+  @tasty-golden@ package.  These helpers are useful for testing
+  the output of functions that return @String@s, @Show@, @ToJSON@ or @ToYAML@
+  instances.
+
+tested-with:
+  GHC ==8.10.7 || ==9.0.2 || ==9.2.4 || ==9.4.5 || ==9.6.6 || ==9.8.2
+
+extra-source-files:
+  CHANGELOG.md
+  README.md
+
+source-repository head
+  type:     git
+  location: https://github.com/bellroy/tasty-golden-extra.git
+
+common deps
+  build-depends:
+    , aeson           >=2.1        && <2.3
+    , aeson-diff      ^>=1.1.0.13
+    , aeson-pretty    ^>=0.8.10
+    , base            >=4.14       && <4.20
+    , bytestring      >=0.10       && <0.13
+    , pretty-show     ^>=1.10
+    , pretty-simple   ^>=4.1.3.0
+    , tasty           ^>=1.5.2
+    , tasty-discover  ^>=5.0.0
+    , tasty-golden    ^>=2.3.5
+    , text            ^>=1.2       || ^>=2.0 || ^>=2.1
+    , yaml            ^>=0.11.11.2
+
+common opts
+  default-language:   Haskell2010
+  default-extensions:
+    DuplicateRecordFields
+    OverloadedStrings
+
+  ghc-options:
+    -Wall -Wcompat -Widentities -Wincomplete-record-updates
+    -Wincomplete-uni-patterns -Werror=incomplete-patterns
+    -Wredundant-constraints -Wpartial-fields -Wtabs
+    -Wmissing-local-signatures -fhelpful-errors
+    -fprint-expanded-synonyms -fwarn-unused-do-bind
+
+library
+  import:          deps, opts
+  ghc-options:     -Wunused-packages
+  hs-source-dirs:  src
+
+  -- cabal-fmt: expand src/
+  exposed-modules:
+    Test.Tasty.Golden.Extra.GoldenVsShow
+    Test.Tasty.Golden.Extra.GoldenVsString
+    Test.Tasty.Golden.Extra.GoldenVsToJSON
+    Test.Tasty.Golden.Extra.GoldenVsToYAML
+    Test.Tasty.Golden.Extra.Internal
