diff --git a/CHANGELOG.md b/CHANGELOG.md
new file mode 100644
--- /dev/null
+++ b/CHANGELOG.md
@@ -0,0 +1,16 @@
+# Changelog
+
+All notable changes to `servant-routes-golden` will be documented in this file.
+
+The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
+and this project adheres to [Haskell Package Versioning Policy](https://pvp.haskell.org).
+
+## [Unreleased]
+
+## [0.1.0.0] - 10.06.2025
+
+- Use the `ToJSON` instance of `Routes` to generate golden tests for an API
+- Test suite for the package uses these golden tests on a dummy API
+
+[unreleased]: https://github.com/fpringle/servant-routes/compare/golden-v0.1.0.0...HEAD
+[0.1.0.0]: https://github.com/fpringle/servant-routes/releases/tag/golden-v0.1.0.0
diff --git a/LICENSE b/LICENSE
new file mode 100644
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,30 @@
+Copyright (c) 2025, Frederick Pringle
+
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+    * Redistributions of source code must retain the above copyright
+      notice, this list of conditions and the following disclaimer.
+
+    * 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.
+
+    * Neither the name of Frederick Pringle nor the names of other
+      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
+OWNER 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,107 @@
+# servant-routes-golden
+
+This package lets us define [Golden tests](https://ro-che.info/articles/2017-12-04-golden-tests) using the `HasRoutes` class from [servant-routes](https://github.com/fpringle/servant-routes/blob/main/servant-routes#readme) and the [hspec-golden](https://hackage.haskell.org/package/hspec-golden) library.
+
+See `Servant.API.Routes.Golden` for reference documentation.
+
+## Example
+
+```haskell
+-- file src/API.hs
+module API where
+
+import Servant.API
+
+type UserAPI =
+  "users"
+    :> ( "list" :> Get '[JSON] [User]
+          :<|> "create" :> ReqBody '[JSON] UserCreateData :> Post '[JSON] UserID
+          :<|> "detail" :> QueryParam' '[Required] "id" UserID :> Get '[JSON] User
+       )
+
+-- file test/APISpec.hs
+
+module APISpec where
+
+import API
+import Servant.API.Routes.Golden
+import Hspec
+
+spec :: Spec
+spec =
+  it "UserAPI" $ goldenRoutes @UserAPI (show ''UserAPI)
+```
+
+We can run `cabal test` to generate the starting "golden file":
+
+```bash
+$ cabal test
+API
+  UserAPI [✔]
+    First time execution. Golden file created.
+```
+
+Of course, if we run the test again, it should pass:
+
+```bash
+$ cabal test
+API
+  UserAPI [✔]
+    Golden and Actual output didn't change
+```
+
+But let's say we change the API definition slightly:
+
+```diff
+type UserAPI =
+  "users"
+    :> ( "list" :> Get '[JSON] [User]
+-          :<|> "create" :> ReqBody '[JSON] UserCreateData :> Post '[JSON] UserID
++          :<|> "create-new" :> ReqBody '[JSON] UserCreateData :> Post '[JSON] UserID
+          :<|> "detail" :> QueryParam' '[Required] "id" UserID :> Get '[JSON] User
+       )
+```
+
+Then when we run the tests again:
+
+```bash
+$ cabal test
+API
+  UserAPI [✘]
+    Files golden and actual not match
+
+Failures:
+
+  test/APISpec.hs:9:3: 
+  1) Servant.API.Routes.Golden UserAPI
+       expected: {
+                     "/users/create": {
+                         "POST": {
+                             "auths": [],
+                             "description": null,
+                             "method": "POST",
+                             "params": [],
+                             "path": "/users/create",
+                             "request_body": "UserCreateData",
+                             "request_headers": [],
+                             "response": {
+                 @@ 45 lines omitted @@
+                 
+        but got: {
+                     "/users/create-new": {
+                         "POST": {
+                             "auths": [],
+                             "description": null,
+                             "method": "POST",
+                             "params": [],
+                             "path": "/users/create-new",
+                             "request_body": "UserCreateData",
+                             "request_headers": [],
+                             "response": {
+                 @@ 45 lines omitted @@
+```
+
+This forces us to either:
+
+- acknowledge that the golden files should be updated, and do so by running the [hgold CLI](https://github.com/stackbuilders/hspec-golden?tab=readme-ov-file#install-cli), or
+- realise that our changes resulted in a change to the API which we didn't anticipate, so we have to fix them.
diff --git a/servant-routes-golden.cabal b/servant-routes-golden.cabal
new file mode 100644
--- /dev/null
+++ b/servant-routes-golden.cabal
@@ -0,0 +1,99 @@
+cabal-version:      3.0
+name:               servant-routes-golden
+version:            0.1.0.0
+synopsis:           Golden test your Servant APIs using `servant-routes`
+description:
+    See the documentation of 'Servant.API.Routes.Golden'.
+license:            BSD-3-Clause
+license-file:       LICENSE
+author:             Frederick Pringle
+maintainer:         freddyjepringle@gmail.com
+copyright:          Copyright(c) Frederick Pringle 2025
+homepage:           https://github.com/fpringle/servant-routes
+bug-reports:        https://github.com/fpringle/servant-routes/issues
+category:           Servant, Web
+build-type:         Simple
+extra-doc-files:    CHANGELOG.md
+                    README.md
+
+tested-with:
+    GHC == 8.8.4
+  , GHC == 8.10.7
+  , GHC == 9.0.2
+  , GHC == 9.2.4
+  , GHC == 9.2.8
+  , GHC == 9.4.2
+  , GHC == 9.4.5
+  , GHC == 9.6.1
+  , GHC == 9.6.7
+  , GHC == 9.8.2
+  , GHC == 9.10.2
+  , GHC == 9.12.2
+
+source-repository head
+  type:           git
+  location:       https://github.com/fpringle/servant-routes
+  subdir:         servant-routes-golden
+
+common warnings
+  ghc-options: -Wall -Wno-unused-do-bind
+
+common deps
+  build-depends:
+    , base >= 4.13 && < 5
+    , aeson >= 2.0 && < 2.3
+    , text >= 1.2 && < 2.2
+    , aeson-pretty >= 0.8.8 && < 0.9
+    , hspec-core >= 2.10.0 && < 2.12
+    , hspec-golden >= 0.2 && < 0.3
+    , servant-routes >= 0.1.0.0 && < 0.2
+
+common extensions
+  default-extensions:
+    DeriveGeneric
+    DerivingVia 
+    FlexibleContexts
+    FlexibleInstances
+    LambdaCase
+    NamedFieldPuns
+    OverloadedStrings
+    PackageImports
+    RecordWildCards
+    ScopedTypeVariables
+    TypeApplications
+    ViewPatterns
+    DataKinds
+    AllowAmbiguousTypes
+    TypeFamilies
+    TypeOperators
+
+library
+  import:
+      warnings
+    , deps
+    , extensions
+  ghc-options: -Wunused-packages
+  exposed-modules:
+    Servant.API.Routes.Golden
+  hs-source-dirs:   src
+  default-language: Haskell2010
+
+test-suite servant-routes-golden-test
+  import:
+      warnings
+    , deps
+    , extensions
+  default-language: Haskell2010
+  type:             exitcode-stdio-1.0
+  hs-source-dirs:   test
+  main-is:          Spec.hs
+  other-modules:
+    Servant.API.Routes.GoldenSpec
+  build-tool-depends:
+      hspec-discover:hspec-discover
+  ghc-options:      -Wno-orphans
+  build-depends:
+    , servant-routes-golden
+    , servant >= 0.17 && < 0.21
+    , hspec >= 2.9 && < 2.12
+    , QuickCheck >= 2.14 && < 2.16
diff --git a/src/Servant/API/Routes/Golden.hs b/src/Servant/API/Routes/Golden.hs
new file mode 100644
--- /dev/null
+++ b/src/Servant/API/Routes/Golden.hs
@@ -0,0 +1,54 @@
+{- |
+Module      : Servant.API.Routes.Golden
+Copyright   : (c) Frederick Pringle, 2025
+License     : BSD-3-Clause
+Maintainer  : frederick.pringle@fpringle.com
+
+The 'HasRoutes' class allows us to generate a list of 'Route's from a Servant
+API type. Using "hspec-golden", we can generate automatic 'G.Golden' tests from
+these APIs. If such a test fails, we know that the shape of our API has changed.
+Therefore we must either:
+
+- decide that the shape change is correct, and acknowledge that the golden files
+  should be updated, by running the
+  [hgold CLI](https://github.com/stackbuilders/hspec-golden?tab=readme-ov-file#install-cli), or
+- realise that our changes resulted in a change to the API which we didn't
+  intend/anticipate, so we have to fix them.
+-}
+module Servant.API.Routes.Golden
+  ( -- * Generating golden tests using HasRoutes
+    goldenRoutes
+  , goldenRoutesSpec
+  )
+where
+
+import Control.Monad ((>=>))
+import qualified Data.Aeson as A
+import qualified Data.Aeson.Encode.Pretty as P
+import qualified Data.Text as T
+import qualified Data.Text.Lazy as TL
+import qualified Data.Text.Lazy.Encoding as TLE
+import qualified Data.Text.Lazy.IO as TL
+import Servant.API.Routes
+import qualified Test.Hspec.Core.Spec as H
+import qualified Test.Hspec.Golden as G
+
+{- | Given an API type with a 'HasRoutes' instance, we can create a 'G.Golden' test
+on the t'Routes' representation of that API. This can be used to automatically track
+changes to the API shape during testing. For a concrete example see the
+[README](https://github.com/fpringle/servant-routes/blob/main/servant-routes-golden/README.md).
+-}
+goldenRoutes :: forall api. (HasRoutes api) => String -> G.Golden A.Value
+goldenRoutes name =
+  (G.defaultGolden name "")
+    { G.output = A.toJSON . Routes $ getRoutes @api
+    , G.encodePretty = T.unpack . TL.toStrict . pretty
+    , G.writeToFile = \fp -> TL.writeFile fp . pretty
+    , G.readFromFile = A.eitherDecodeFileStrict @A.Value >=> either fail pure
+    }
+  where
+    pretty = TLE.decodeUtf8 . P.encodePretty' (P.defConfig {P.confCompare = compare})
+
+-- | Generate a 'H.Spec' for your API type.
+goldenRoutesSpec :: forall api. (HasRoutes api) => String -> H.Spec
+goldenRoutesSpec = H.it "Generates the correct Routes" . goldenRoutes @api
diff --git a/test/Servant/API/Routes/GoldenSpec.hs b/test/Servant/API/Routes/GoldenSpec.hs
new file mode 100644
--- /dev/null
+++ b/test/Servant/API/Routes/GoldenSpec.hs
@@ -0,0 +1,41 @@
+{-# LANGUAGE CPP #-}
+{-# LANGUAGE TemplateHaskellQuotes #-}
+
+module Servant.API.Routes.GoldenSpec
+  ( spec
+  )
+where
+
+import qualified Data.Text as T
+import GHC.Generics
+import Servant.API
+import Servant.API.Routes.Golden
+import Test.Hspec as H
+
+type SubAPI = ReqBody '[JSON] String :> Post '[JSON] Int
+
+type SubAPI2 = Header "h1" T.Text :> "x" :> ("y" :> Put '[JSON] String :<|> SubAPI)
+
+type SubAPI3 =
+  Header "h2" T.Text
+    :> "x2"
+    :> ( "y1" :> Description "desc" :> Put '[JSON] String
+          :<|> "z1" :> Header' '[Optional] "h3" Int :> Get '[JSON] [Integer]
+       )
+
+#if MIN_VERSION_servant(0,19,0)
+data API mode = API
+  { ep1 :: mode :- "sub1" :> SubAPI
+  , ep2 :: mode :- "sub2" :> SubAPI2
+  , ep3 :: mode :- "sub3" :> SubAPI3
+  } deriving Generic
+#endif
+
+spec :: H.Spec
+spec = do
+  it "SubAPI" $ goldenRoutes @SubAPI (show ''SubAPI)
+  it "SubAPI2" $ goldenRoutes @SubAPI2 (show ''SubAPI2)
+  it "SubAPI3" $ goldenRoutes @SubAPI3 (show ''SubAPI3)
+#if MIN_VERSION_servant(0,19,0)
+  it "NamedRoutes API" $ goldenRoutes @(NamedRoutes API) (show ''API)
+#endif
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 hspec-discover #-}
