diff --git a/CHANGELOG.md b/CHANGELOG.md
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,11 @@
+0.10.4.3
+--------
+
+_Andreas Abel, 2025-08-27_
+
+- Remove old code for GHC 7
+- Tested with GHC 8.0 - 9.14 alpha1
+
 0.10.4
 ======
 
@@ -53,5 +61,3 @@
 [https://github.com/GaloisInc/cereal/commit/47d839609413e3e9d1147b99c34ae421ae36bced](https://github.com/GaloisInc/cereal/commit/47d839609413e3e9d1147b99c34ae421ae36bced)
 
 [https://github.com/GaloisInc/cereal/issues/35](https://github.com/GaloisInc/cereal/issues/35)
-
-
diff --git a/safecopy.cabal b/safecopy.cabal
--- a/safecopy.cabal
+++ b/safecopy.cabal
@@ -1,9 +1,6 @@
--- safecopy.cabal auto-generated by cabal init. For additional
--- options, see
--- http://www.haskell.org/cabal/release/cabal-latest/doc/users-guide/authors.html#pkg-descr.
--- The name of the package.
+Cabal-version:       1.18
 Name:                safecopy
-Version:             0.10.4.2
+Version:             0.10.4.3
 Synopsis:            Binary serialization with version control.
 Description:         An extension to Data.Serialize with built-in version control.
 Homepage:            https://github.com/acid-state/safecopy
@@ -13,44 +10,55 @@
 -- Copyright:
 Category:            Data, Parsing
 Build-type:          Simple
-Extra-source-files: CHANGELOG.md
-Cabal-version:       >=1.10
-tested-with:         GHC==8.0.2, GHC==8.2.2, GHC==8.4.4, GHC==8.6.5, GHC==8.8.3, GHC==8.10.1
 
+Extra-doc-files:  CHANGELOG.md
+
+tested-with:
+  GHC == 9.14.1
+  GHC == 9.12.2
+  GHC == 9.10.2
+  GHC == 9.8.4
+  GHC == 9.6.7
+  GHC == 9.4.8
+  GHC == 9.2.8
+  GHC == 9.0.2
+  GHC == 8.10.7
+  GHC == 8.8.4
+  GHC == 8.6.5
+  GHC == 8.4.4
+  GHC == 8.2.2
+  GHC == 8.0.2
+
 Source-repository head
   type:          git
-  location:      git://github.com/acid-state/safecopy.git
+  location:      https://github.com/acid-state/safecopy.git
 
 
 Library
   Default-language:    Haskell2010
-  -- Modules exported by the library.
   Exposed-modules:     Data.SafeCopy
                        Data.SafeCopy.Internal
 
   Hs-Source-Dirs:      src/
 
-  -- Packages needed in order to build this package.
-  Build-depends:       base >=4.9 && <5,
-                       array < 0.6,
-                       cereal >= 0.5 && < 0.6,
-                       bytestring < 0.12,
-                       generic-data >= 0.3,
-                       containers >= 0.3 && < 0.7,
-                       old-time < 1.2,
-                       template-haskell < 2.18,
-                       text < 1.3,
-                       time < 1.12,
-                       transformers < 0.6,
-                       vector >= 0.10 && < 0.13
+  -- Lower bounds are chosen to match LTS 7.24 (GHC 8.0)
+  Build-depends:       base             >= 4.9       && < 5
+                     , array            >= 0.5.1.1   && < 0.6
+                     , cereal           >= 0.5.4.0   && < 0.6
+                     , bytestring       >= 0.10.8.1  && < 0.13
+                     , generic-data     >= 0.3.0.0   && < 2
+                     , containers       >= 0.5.7.1   && < 1
+                     , old-time         >= 1.1.0.3   && < 1.2
+                     , template-haskell >= 2.11.0.0  && < 2.25
+                     , text             >= 1.2.2.2   && < 1.3 || >= 2.0 && < 2.2
+                     , time             >= 1.6.0.1   && < 2
+                     , transformers     >= 0.5.2.0   && < 0.7
+                     , vector           >= 0.11.0.0  && < 0.14
 
-  -- Modules not exported by this package.
-  Other-modules:       Data.SafeCopy.Instances, Data.SafeCopy.SafeCopy,
+  Other-modules:       Data.SafeCopy.Instances
+                       Data.SafeCopy.SafeCopy
                        Data.SafeCopy.Derive
 
-  -- Extra tools (e.g. alex, hsc2hs, ...) needed to build the source.
-  -- Build-tools:
-
   GHC-Options:         -Wall
 
   cpp-options: -DDEFAULT_SIGNATURES -DSAFE_HASKELL
@@ -61,9 +69,19 @@
   Main-is:             instances.hs
   Hs-Source-Dirs:      test/
   GHC-Options:         -Wall -threaded -rtsopts -with-rtsopts=-N
-  Build-depends:       base, cereal, template-haskell, safecopy,
-                       containers, time, array, vector, lens >= 4.7 && < 5.1,
-                       lens-action, tasty, tasty-quickcheck, quickcheck-instances, QuickCheck
+  Build-depends:       base
+                     , array
+                     , cereal
+                     , containers
+                     , safecopy
+                     , template-haskell
+                     , time
+                     , vector
+                     -- new dependencies:
+                     , lens >= 4.7 && < 6
+                     , lens-action
+                     , tasty
+                     , tasty-quickcheck
 
 Test-suite generic
   Default-language:    Haskell2010
@@ -71,4 +89,8 @@
   Main-is:             generic.hs
   Hs-Source-Dirs:      test/
   GHC-Options:         -Wall -threaded -rtsopts -with-rtsopts=-N
-  Build-depends:       base, bytestring, cereal, safecopy, HUnit
+  Build-depends:       base
+                     , bytestring
+                     , cereal
+                     , safecopy
+                     , HUnit
diff --git a/src/Data/SafeCopy.hs b/src/Data/SafeCopy.hs
--- a/src/Data/SafeCopy.hs
+++ b/src/Data/SafeCopy.hs
@@ -16,6 +16,8 @@
 -- can change the definition and binary format of a type nested deep within
 -- other types without problems.
 --
+-- = Migration
+--
 -- Consider this scenario. You want to store your contact list on disk
 -- and so write the following code:
 --
@@ -74,6 +76,31 @@
 -- With this, you reflect on your code and you are happy. You feel confident in the safety of
 -- your data and you know you can remove @Contacts_v0@ once you no longer wish to support
 -- that legacy format.
+--
+-- = Retiring Migrations
+--
+-- There may come a time when you have to remove @Contacts_v0@.
+-- Perhaps it uses types you want to remove from your build to
+-- decrease its size.  Perhaps it has constraints such as @Enum@ which
+-- are imposed on your new @Contacts@ type via the @SafeCopy@
+-- instance.
+--
+-- In any case, if you are using @safecopy@ incombination with
+-- @acid-state@, some care must be taken when removing @Contacts_v0@.
+-- The following steps must be taken to add a new type and remove the old:
+--
+--   1. Add the migration as described above.
+--   2. Run the server with the new migration on /all important data/.  This
+--      will cause the type to be modified in the running program.
+--   3. /Restart/ the server with the new migration on /all important data/.  This
+--      causes checkpoints to be written that only contain the new type.
+--   4. Remove the old type from your source code, changing the @kind@ of
+--      the new type from @extension@ to @base@. Build and deploy.
+--
+-- If you omit any of these steps it is a certainty that you will
+-- proceed happily with your development thinking all is grand, and
+-- then when you go to deploy your live system the migration will fail.
+
 module Data.SafeCopy
     (
       safeGet
diff --git a/src/Data/SafeCopy/Derive.hs b/src/Data/SafeCopy/Derive.hs
--- a/src/Data/SafeCopy/Derive.hs
+++ b/src/Data/SafeCopy/Derive.hs
@@ -1,10 +1,5 @@
 {-# LANGUAGE TemplateHaskell, CPP #-}
 
--- Hack for bug in older Cabal versions
-#ifndef MIN_VERSION_template_haskell
-#define MIN_VERSION_template_haskell(x,y,z) 1
-#endif
-
 module Data.SafeCopy.Derive where
 
 import Data.Serialize (getWord8, putWord8, label)
diff --git a/src/Data/SafeCopy/Instances.hs b/src/Data/SafeCopy/Instances.hs
--- a/src/Data/SafeCopy/Instances.hs
+++ b/src/Data/SafeCopy/Instances.hs
@@ -1,13 +1,13 @@
 {-# LANGUAGE CPP #-}
-{-# LANGUAGE DeriveDataTypeable, FlexibleContexts, UndecidableInstances, TypeFamilies #-}
+{-# LANGUAGE FlexibleContexts #-}
+{-# LANGUAGE TypeFamilies #-}
+{-# LANGUAGE UndecidableInstances #-}
 {-# OPTIONS_GHC -fno-warn-orphans #-}
+
 module Data.SafeCopy.Instances where
 
 import Data.SafeCopy.SafeCopy
 
-#if !MIN_VERSION_base(4,8,0)
-import           Control.Applicative
-#endif
 import           Control.Monad
 import qualified Data.Array as Array
 import qualified Data.Array.Unboxed as UArray
@@ -173,7 +173,7 @@
 --
 -- https://github.com/GaloisInc/cereal/commit/47d839609413e3e9d1147b99c34ae421ae36bced
 -- https://github.com/GaloisInc/cereal/issues/35
-newtype CerealFloat040 = CerealFloat040 { unCerealFloat040 :: Float} deriving (Show, Typeable)
+newtype CerealFloat040 = CerealFloat040 { unCerealFloat040 :: Float} deriving (Show)
 instance SafeCopy CerealFloat040 where
     getCopy = contain (CerealFloat040 <$> liftM2 encodeFloat get get)
     putCopy (CerealFloat040 float) = contain (put (decodeFloat float))
@@ -194,7 +194,7 @@
 --
 -- https://github.com/GaloisInc/cereal/commit/47d839609413e3e9d1147b99c34ae421ae36bced
 -- https://github.com/GaloisInc/cereal/issues/35
-newtype CerealDouble040 = CerealDouble040 { unCerealDouble040 :: Double} deriving (Show, Typeable)
+newtype CerealDouble040 = CerealDouble040 { unCerealDouble040 :: Double} deriving (Show)
 instance SafeCopy CerealDouble040 where
     getCopy = contain (CerealDouble040 <$> liftM2 encodeFloat get get)
     putCopy (CerealDouble040 double) = contain (put (decodeFloat double))
diff --git a/test/instances.hs b/test/instances.hs
--- a/test/instances.hs
+++ b/test/instances.hs
@@ -5,17 +5,13 @@
 
 {-# OPTIONS_GHC -fno-warn-orphans #-}
 
--- Hack for bug in older Cabal versions
-#ifndef MIN_VERSION_template_haskell
-#define MIN_VERSION_template_haskell(x,y,z) 1
-#endif
-
 import Control.Applicative
-import Control.Lens
-import Control.Lens.Action
+import Control.Lens           (transformOn, transformOnOf)
+import Control.Lens.Traversal (Traversal')
+import Control.Lens.Action    ((^!!), act)
 import Data.Array (Array)
 import Data.Array.Unboxed (UArray)
-import Data.Data.Lens
+import Data.Data.Lens         (template)
 import Data.Fixed (Fixed, E1)
 import Data.List
 import Data.SafeCopy
@@ -24,7 +20,6 @@
 import Data.Tree (Tree)
 import Language.Haskell.TH
 import Language.Haskell.TH.Syntax
-import Test.QuickCheck.Instances ()
 import Test.Tasty
 import Test.Tasty.QuickCheck hiding (Fixed, (===))
 import qualified Data.Vector as V
@@ -32,40 +27,11 @@
 import qualified Data.Vector.Storable as VS
 import qualified Data.Vector.Unboxed as VU
 
-#if ! MIN_VERSION_QuickCheck(2,9,0)
-instance (Arbitrary a, Arbitrary b, Arbitrary c, Arbitrary d, Arbitrary e, Arbitrary f) =>
-         Arbitrary (a,b,c,d,e,f) where
-   arbitrary = (,,,,,) <$> arbitrary <*> arbitrary <*> arbitrary <*>
-                           arbitrary <*> arbitrary <*> arbitrary
-
-instance (Arbitrary a, Arbitrary b, Arbitrary c, Arbitrary d, Arbitrary e, Arbitrary f, Arbitrary g) =>
-         Arbitrary (a,b,c,d,e,f,g) where
-   arbitrary = (,,,,,,) <$> arbitrary <*> arbitrary <*> arbitrary <*>
-                            arbitrary <*> arbitrary <*> arbitrary <*> arbitrary
-#endif
-
-#if ! MIN_VERSION_QuickCheck(2,8,2)
-instance (Arbitrary a) => Arbitrary (V.Vector a) where
-   arbitrary = V.fromList <$> arbitrary
-
-instance (Arbitrary a, VP.Prim a) => Arbitrary (VP.Vector a) where
-   arbitrary = VP.fromList <$> arbitrary
-
-instance (Arbitrary a, VS.Storable a) => Arbitrary (VS.Vector a) where
-   arbitrary = VS.fromList <$> arbitrary
-
-instance (Arbitrary a, VU.Unbox a) => Arbitrary (VU.Vector a) where
-   arbitrary = VU.fromList <$> arbitrary
-#endif
-
 deriving instance (Arbitrary a) => Arbitrary (Prim a)
 deriving instance (Eq a) => Eq (Prim a)
 deriving instance (Show a) => Show (Prim a)
 
 deriving instance Eq ZonedTime
-#if ! MIN_VERSION_time(1,6,0)
-deriving instance Show UniversalTime
-#endif
 
 -- | Equality on the 'Right' value, showing the unequal value on failure;
 -- or explicit failure using the 'Left' message without equality testing.
@@ -105,25 +71,14 @@
 
    safecopy <- reify ''SafeCopy
    preds <- 'prop_inverse ^!! act reify . (template :: Traversal' Info Pred)
-#if !MIN_VERSION_template_haskell(2,10,0)
-   classes <- mapM reify [ name | ClassP name _ <- preds ]
-#else
---   print preds
-
    classes <-
          case preds of
            [ForallT _ cxt' _] ->
               mapM reify [ name | AppT (ConT name) _ <- cxt' ]
            _ -> error "FIXME: fix this code to handle this case."
---   classes <- mapM reify [ ]
-#endif
    def <- a
 
-#if MIN_VERSION_template_haskell(2,11,0)
    let instances (ClassI _ decs) = [ typ | InstanceD _ _ (AppT _ typ) _ <- decs ]
-#else
-   let instances (ClassI _ decs) = [ typ | InstanceD _ (AppT _ typ) _ <- decs ]
-#endif
        instances _ = []
        types = map instances classes
 
@@ -147,11 +102,6 @@
                ($(downsize typ) (prop_inverse :: $(return typ) -> Property)) |]
 
        props = listE . map prop
-
-#if !MIN_VERSION_template_haskell(2,8,0)
-       -- 'report' throws warnings in template-haskell-2.8.0.0
-       reportWarning = report False
-#endif
 
    mapM_ (\typ -> reportWarning $ "not tested: " ++ name typ) untested
 
