diff --git a/changelog.md b/changelog.md
--- a/changelog.md
+++ b/changelog.md
@@ -1,3 +1,6 @@
+0.2.2.1
+* Drop dependency on derive in tests.
+
 0.2.2.0
 * Internally use attoparsec's numeric parser. Raise lower bounds on attoparsec.
 * Allow blank fragments.
diff --git a/test/URI/ByteString/Arbitrary.hs b/test/URI/ByteString/Arbitrary.hs
--- a/test/URI/ByteString/Arbitrary.hs
+++ b/test/URI/ByteString/Arbitrary.hs
@@ -1,13 +1,16 @@
-{-# LANGUAGE FlexibleInstances #-}
-{-# LANGUAGE TemplateHaskell   #-}
+{-# LANGUAGE FlexibleContexts      #-}
+{-# LANGUAGE FlexibleInstances     #-}
+{-# LANGUAGE MultiParamTypeClasses #-}
 {-# OPTIONS_GHC -fno-warn-orphans #-}
 module URI.ByteString.Arbitrary where
 
 
 -------------------------------------------------------------------------------
 import           Control.Applicative
-import           Data.Derive.Arbitrary     (makeArbitrary)
-import           Data.DeriveTH             (derive)
+import           Data.Proxy                (Proxy (..))
+import qualified Generics.SOP              as SOP
+import qualified Generics.SOP.GGP          as SOP
+import           GHC.Generics              (Generic)
 import           Test.QuickCheck
 import           Test.QuickCheck.Instances ()
 -------------------------------------------------------------------------------
@@ -17,6 +20,19 @@
 -------------------------------------------------------------------------------
 
 
+-- this workaround can go away when
+-- <https://github.com/nick8325/quickcheck/pull/40> is merged.
+sopArbitrary :: (Generic a, SOP.GTo a, SOP.All SOP.SListI (SOP.GCode a), SOP.All2 Arbitrary (SOP.GCode a)) => Gen a
+sopArbitrary = fmap SOP.gto sopArbitrary'
+
+
+sopArbitrary' :: (SOP.All SOP.SListI xss, SOP.All2 Arbitrary xss) => Gen (SOP.SOP SOP.I xss)
+sopArbitrary' = oneof (map SOP.hsequence $ SOP.apInjs_POP $ SOP.hcpure p arbitrary)
+  where
+    p :: Proxy Arbitrary
+    p = Proxy
+
+
 instance Arbitrary UserInfo where
   arbitrary = UserInfo <$> arbitrary
                        <*> arbitrary
@@ -73,5 +89,12 @@
                                       <*> arbitrary
                                       <*> arbitrary
 
-$(derive makeArbitrary ''SchemaError)
-$(derive makeArbitrary ''URIParseError)
+
+instance Arbitrary SchemaError where
+  arbitrary = sopArbitrary
+  shrink = genericShrink
+
+
+instance Arbitrary URIParseError where
+  arbitrary = sopArbitrary
+  shrink = genericShrink
diff --git a/uri-bytestring.cabal b/uri-bytestring.cabal
--- a/uri-bytestring.cabal
+++ b/uri-bytestring.cabal
@@ -1,5 +1,5 @@
 name:                uri-bytestring
-version:             0.2.2.0
+version:             0.2.2.1
 synopsis:            Haskell URI parsing as ByteStrings
 description: uri-bytestring aims to be an RFC3986 compliant URI parser that uses efficient ByteStrings for parsing and representing the URI data.
 license:             BSD3
@@ -67,7 +67,6 @@
     , tasty
     , tasty-hunit
     , tasty-quickcheck
-    , derive
     , attoparsec
     , base
     , blaze-builder
@@ -76,6 +75,7 @@
     , quickcheck-instances
     , semigroups
     , containers
+    , generics-sop >= 0.2
   default-language:    Haskell2010
 
   if flag(lib-Werror)
