diff --git a/CHANGES.md b/CHANGES.md
--- a/CHANGES.md
+++ b/CHANGES.md
@@ -1,5 +1,9 @@
 See also https://pvp.haskell.org/faq
 
+## Version 1.4.6.0
+
+  * Use GND&DerivingVia to derive `newtype` intances (`Data.Semigroup`, `Data.Monoid`, `Identity` etc).
+
 ## Version 1.4.5.0
 
   * Drop support for GHCs prior 8.6.5
diff --git a/hashable.cabal b/hashable.cabal
--- a/hashable.cabal
+++ b/hashable.cabal
@@ -1,6 +1,6 @@
 cabal-version:      2.2
 name:               hashable
-version:            1.4.5.0
+version:            1.4.6.0
 synopsis:           A class for types that can be converted to a hash value
 description:
   This package defines a class, 'Hashable', for types that can be converted to a hash value.
@@ -192,12 +192,12 @@
     , ghc-prim
     , hashable
     , HUnit
-    , QuickCheck                  >=2.4.0.1
-    , random                      >=1.0      && <1.3
-    , test-framework              >=0.3.3
-    , test-framework-hunit
-    , test-framework-quickcheck2  >=0.2.9
-    , text                        >=0.11.0.5
+    , QuickCheck        >=2.4.0.1
+    , random            >=1.0      && <1.3
+    , tasty             ^>=1.5
+    , tasty-hunit       ^>=0.10.1
+    , tasty-quickcheck  ^>=0.10.3
+    , text              >=0.11.0.5
 
   if impl(ghc >=9.2)
     build-depends: os-string
diff --git a/src/Data/Hashable/Class.hs b/src/Data/Hashable/Class.hs
--- a/src/Data/Hashable/Class.hs
+++ b/src/Data/Hashable/Class.hs
@@ -1,16 +1,20 @@
-{-# LANGUAGE BangPatterns          #-}
-{-# LANGUAGE CApiFFI               #-}
-{-# LANGUAGE CPP                   #-}
-{-# LANGUAGE DefaultSignatures     #-}
-{-# LANGUAGE FlexibleContexts      #-}
-{-# LANGUAGE MagicHash             #-}
-{-# LANGUAGE MultiParamTypeClasses #-}
-{-# LANGUAGE PackageImports        #-}
-{-# LANGUAGE PolyKinds             #-}
-{-# LANGUAGE ScopedTypeVariables   #-}
-{-# LANGUAGE Trustworthy           #-}
-{-# LANGUAGE TypeFamilies          #-}
-{-# LANGUAGE UnliftedFFITypes      #-}
+{-# LANGUAGE BangPatterns               #-}
+{-# LANGUAGE CApiFFI                    #-}
+{-# LANGUAGE CPP                        #-}
+{-# LANGUAGE DefaultSignatures          #-}
+{-# LANGUAGE DerivingStrategies         #-}
+{-# LANGUAGE FlexibleContexts           #-}
+{-# LANGUAGE GeneralizedNewtypeDeriving #-}
+{-# LANGUAGE MagicHash                  #-}
+{-# LANGUAGE MultiParamTypeClasses      #-}
+{-# LANGUAGE PackageImports             #-}
+{-# LANGUAGE PolyKinds                  #-}
+{-# LANGUAGE ScopedTypeVariables        #-}
+{-# LANGUAGE StandaloneDeriving         #-}
+{-# LANGUAGE StandaloneDeriving         #-}
+{-# LANGUAGE Trustworthy                #-}
+{-# LANGUAGE TypeFamilies               #-}
+{-# LANGUAGE UnliftedFFITypes           #-}
 
 {-# OPTIONS_GHC -fno-warn-deprecations #-}
 
@@ -652,33 +656,19 @@
 
 #if HAS_OS_STRING_filepath || HAS_OS_STRING_os_string
 -- | @since 1.4.2.0
-instance Hashable PosixString where
-    hash (PosixString s) = hash s
-    hashWithSalt salt (PosixString s) = hashWithSalt salt s
+deriving newtype instance Hashable PosixString
 
 -- | @since 1.4.2.0
-instance Hashable WindowsString where
-    hash (WindowsString s) = hash s
-    hashWithSalt salt (WindowsString s) = hashWithSalt salt s
+deriving newtype instance Hashable WindowsString
 
 -- | @since 1.4.2.0
-instance Hashable OsString where
-    hash (OsString s) = hash s
-    hashWithSalt salt (OsString s) = hashWithSalt salt s
+deriving newtype instance Hashable OsString
 #endif
 
 #if HAS_OS_STRING_filepath && HAS_OS_STRING_os_string
-instance Hashable FP.PosixString where
-    hash (FP.PosixString s) = hash s
-    hashWithSalt salt (FP.PosixString s) = hashWithSalt salt s
-
-instance Hashable FP.WindowsString where
-    hash (FP.WindowsString s) = hash s
-    hashWithSalt salt (FP.WindowsString s) = hashWithSalt salt s
-
-instance Hashable FP.OsString where
-    hash (FP.OsString s) = hash s
-    hashWithSalt salt (FP.OsString s) = hashWithSalt salt s
+deriving newtype instance Hashable FP.PosixString
+deriving newtype instance Hashable FP.WindowsString
+deriving newtype instance Hashable FP.OsString
 #endif
 
 #if MIN_VERSION_text(2,0,0)
@@ -811,17 +801,14 @@
     hashWithSalt salt (Version branch tags) =
         salt `hashWithSalt` branch `hashWithSalt` tags
 
-instance Hashable (Fixed a) where
-    hashWithSalt salt (MkFixed i) = hashWithSalt salt i
+deriving newtype instance Hashable (Fixed a)
 
-instance Hashable a => Hashable (Identity a) where
-    hashWithSalt = hashWithSalt1
+deriving newtype instance Hashable a => Hashable (Identity a)
 instance Hashable1 Identity where
     liftHashWithSalt h salt (Identity x) = h salt x
 
 -- Using hashWithSalt1 would cause needless constraint
-instance Hashable a => Hashable (Const a b) where
-    hashWithSalt salt (Const x) = hashWithSalt salt x
+deriving newtype instance Hashable a => Hashable (Const a b)
 
 instance Hashable a => Hashable1 (Const a) where
     liftHashWithSalt = defaultLiftHashWithSalt
@@ -843,11 +830,8 @@
 instance Hashable1 NE.NonEmpty where
     liftHashWithSalt h salt (a NE.:| as) = liftHashWithSalt h (h salt a) as
 
-instance Hashable a => Hashable (Semi.Min a) where
-    hashWithSalt p (Semi.Min a) = hashWithSalt p a
-
-instance Hashable a => Hashable (Semi.Max a) where
-    hashWithSalt p (Semi.Max a) = hashWithSalt p a
+deriving newtype instance Hashable a => Hashable (Semi.Min a)
+deriving newtype instance Hashable a => Hashable (Semi.Max a)
 
 -- | __Note__: Prior to @hashable-1.3.0.0@ the hash computation included the second argument of 'Arg' which wasn't consistent with its 'Eq' instance.
 --
@@ -855,22 +839,12 @@
 instance Hashable a => Hashable (Semi.Arg a b) where
     hashWithSalt p (Semi.Arg a _) = hashWithSalt p a
 
-instance Hashable a => Hashable (Semi.First a) where
-    hashWithSalt p (Semi.First a) = hashWithSalt p a
-
-
-instance Hashable a => Hashable (Semi.Last a) where
-    hashWithSalt p (Semi.Last a) = hashWithSalt p a
-
-
-instance Hashable a => Hashable (Semi.WrappedMonoid a) where
-    hashWithSalt p (Semi.WrapMonoid a) = hashWithSalt p a
-
+deriving newtype instance Hashable a => Hashable (Semi.First a)
+deriving newtype instance Hashable a => Hashable (Semi.Last a)
+deriving newtype instance Hashable a => Hashable (Semi.WrappedMonoid a)
 
 #if !MIN_VERSION_base(4,16,0)
-instance Hashable a => Hashable (Semi.Option a) where
-    hashWithSalt p (Semi.Option a) = hashWithSalt p a
-
+deriving newtype instance Hashable a => Hashable (Semi.Option a)
 #endif
 
 -- TODO: this instance is removed as there isn't Eq1 Min/Max, ...
diff --git a/tests/Main.hs b/tests/Main.hs
--- a/tests/Main.hs
+++ b/tests/Main.hs
@@ -5,10 +5,10 @@
 
 import Properties (properties)
 import Regress (regressions)
-import Test.Framework (defaultMain, testGroup)
+import Test.Tasty (defaultMain, testGroup)
 
 main :: IO ()
-main = defaultMain [
-         testGroup "properties" properties
-       , testGroup "regressions" regressions
-       ]
+main = defaultMain $ testGroup "hashable"
+    [ testGroup "properties" properties
+    , testGroup "regressions" regressions
+    ]
diff --git a/tests/Properties.hs b/tests/Properties.hs
--- a/tests/Properties.hs
+++ b/tests/Properties.hs
@@ -24,8 +24,8 @@
 import GHC.ST (ST(..), runST)
 import GHC.Word (Word8(..))
 import Test.QuickCheck hiding ((.&.))
-import Test.Framework (Test, testGroup)
-import Test.Framework.Providers.QuickCheck2 (testProperty)
+import Test.Tasty (TestTree, testGroup)
+import Test.Tasty.QuickCheck (testProperty)
 import GHC.Generics
 
 import qualified Data.ByteString.Short as BS
@@ -225,7 +225,7 @@
 pLiftedHashed :: Int -> Hashed (Either Int String) -> Bool
 pLiftedHashed s h = hashWithSalt s h == hashWithSalt1 s h
 
-properties :: [Test]
+properties :: [TestTree]
 properties =
     [ testProperty "bernstein" pHash
     , testGroup "text"
diff --git a/tests/Regress.hs b/tests/Regress.hs
--- a/tests/Regress.hs
+++ b/tests/Regress.hs
@@ -4,11 +4,10 @@
 
 module Regress (regressions) where
 
-import qualified Test.Framework as F
+import Test.Tasty (TestTree, testGroup)
 import Control.Monad (when)
-import Test.Framework.Providers.HUnit (testCase)
-import Test.HUnit (Assertion, assertFailure, (@?=))
-import Test.Framework.Providers.QuickCheck2 (testProperty)
+import Test.Tasty.HUnit (testCase, Assertion, assertFailure, (@?=))
+import Test.Tasty.QuickCheck (testProperty)
 import GHC.Generics (Generic)
 import Data.List (nub)
 import Data.Fixed (Pico)
@@ -33,7 +32,7 @@
     | x == y    = assertFailure msg
     | otherwise = return ()
 
-regressions :: [F.Test]
+regressions :: [TestTree]
 regressions = [] ++
 #ifdef HAVE_MMAP
     Mmap.regressions ++
@@ -41,7 +40,7 @@
         (hash (1 :: Pico) == hash (2 :: Pico)) @?= False
     ] ++
 #endif
-    [ F.testGroup "Generic: sum of nullary constructors"
+    [ testGroup "Generic: sum of nullary constructors"
         [ testCase "0" $ nullaryCase 0 S0
         , testCase "1" $ nullaryCase 1 S1
         , testCase "2" $ nullaryCase 2 S2
@@ -72,7 +71,7 @@
 #endif
         hash ("hello world" :: Text) @?= expected
 #endif
-    , F.testGroup "concatenation"
+    , testGroup "concatenation"
         [ testCase "String" $ do
             let lhs, rhs :: (String, String)
                 lhs = ("foo", "bar")
diff --git a/tests/Regress/Mmap.hsc b/tests/Regress/Mmap.hsc
--- a/tests/Regress/Mmap.hsc
+++ b/tests/Regress/Mmap.hsc
@@ -14,8 +14,8 @@
 import Foreign.Ptr (Ptr, intPtrToPtr, nullPtr, plusPtr)
 import GHC.ForeignPtr (newForeignPtr_)
 import System.Posix.Types (COff(..))
-import Test.Framework (Test)
-import Test.Framework.Providers.HUnit (testCase)
+import Test.Tasty (TestTree)
+import Test.Tasty.HUnit (testCase)
 import qualified Data.ByteString as B
 
 withMapping :: (Ptr a -> Int -> IO ()) -> IO ()
@@ -43,7 +43,7 @@
     forM_ (B.tails bs0) $ \bs -> do
       evaluate (hash bs)
 
-regressions :: [Test]
+regressions :: [TestTree]
 regressions = [
    testCase "hashNearPageBoundary" hashNearPageBoundary
  ]
