diff --git a/changelog.md b/changelog.md
--- a/changelog.md
+++ b/changelog.md
@@ -1,3 +1,13 @@
+# Version 0.4.3
+
+* Builds with GHC 9.0.1.
+
+* `Producer'` replaced with `Proxy`. See `pipes` 
+  issue #224.
+
+* Use QuickCheck instead of SmallCheck for tests.
+
+
 # Version 0.4.2
 
 * Remove upper bound on dependencies other than base.
diff --git a/pipes-binary.cabal b/pipes-binary.cabal
--- a/pipes-binary.cabal
+++ b/pipes-binary.cabal
@@ -1,8 +1,8 @@
 name:               pipes-binary
-version:            0.4.2
+version:            0.4.3
 license:            BSD3
 license-file:       LICENSE
-copyright:          Copyright (c) Renzo Carbonara 2013-2018
+copyright:          Copyright (c) Renzo Carbonara 2013-2021
 author:             Renzo Carbonara
 maintainer:         renλren.zone
 stability:          Experimental
@@ -11,7 +11,7 @@
 category:           Pipes
 build-type:         Simple
 synopsis:           Encode and decode binary streams using the pipes and binary libraries.
-cabal-version:      >=1.8
+cabal-version:      >=1.10
 extra-source-files: README.md PEOPLE changelog.md
 description:
   Encode and decode binary Pipes streams using the @binary@ library.
@@ -27,6 +27,7 @@
     hs-source-dirs:    src
     exposed-modules:   Pipes.Binary
     ghc-options:       -Wall -O2
+    default-language:  Haskell2010
     build-depends:
           base             >= 4.5     && < 5
         , binary           >= 0.6
@@ -41,6 +42,7 @@
     type:              exitcode-stdio-1.0
     hs-source-dirs:    tests
     main-is:           Main.hs
+    default-language:  Haskell2010
     build-depends:
           base
         , binary
@@ -50,8 +52,7 @@
         , pipes
         , pipes-binary
         , pipes-parse
-        , smallcheck       >= 1.0
         , tasty            >= 0.8
         , tasty-hunit      >= 0.8
-        , tasty-smallcheck >= 0.2
+        , tasty-quickcheck >= 0.9
         , transformers
diff --git a/src/Pipes/Binary.hs b/src/Pipes/Binary.hs
--- a/src/Pipes/Binary.hs
+++ b/src/Pipes/Binary.hs
@@ -70,6 +70,10 @@
 
 -- | Convert a value to a byte stream.
 --
+-- @
+-- 'encode' :: ('Monad' m, 'Binary' a) => a -> 'Producer'' 'ByteString' m ()
+-- @
+--
 -- Keep in mind that a single encode value might be split into many 'ByteString'
 -- chunks, that is, the lenght of the obtained 'Producer' might be greater than
 -- 1.
@@ -78,9 +82,9 @@
 -- 'Binary' instances as they flow downstream using:
 --
 -- @
--- 'for' 'cat' 'encode' :: ('Monad' m, 'Binary' a) => 'Pipe' a 'B.ByteString' m r
+-- 'for' 'cat' 'encode' :: ('Monad' m, 'Binary' a) => 'Pipe' a 'ByteString' m r
 -- @
-encode :: (Monad m, Binary a) => a -> Producer' ByteString m ()
+encode :: (Monad m, Binary a) => a -> Proxy x' x () ByteString m ()
 encode = encodePut . put
 {-# INLINABLE encode #-}
 {-# RULES "p >-> for cat encode" forall p .
@@ -88,8 +92,12 @@
   #-}
 
 -- | Like 'encode', except this uses an explicit 'Put'.
-encodePut :: (Monad m) => Put -> Producer' ByteString m ()
-encodePut = Pipes.ByteString.fromLazy . Put.runPut
+--
+-- @
+-- 'encodePut' :: ('Monad' m) => 'Put' -> 'Producer'' 'ByteString' m ()
+-- @
+encodePut :: (Monad m) => Put -> Proxy x' x () ByteString m ()
+encodePut = \p -> Pipes.ByteString.fromLazy (Put.runPut p)
 {-# INLINABLE encodePut #-}
 {-# RULES "p >-> for cat encodePut" forall p.
     p >-> for cat encodePut = for p encodePut
diff --git a/tests/Main.hs b/tests/Main.hs
--- a/tests/Main.hs
+++ b/tests/Main.hs
@@ -5,7 +5,8 @@
 import qualified Test.Tasty                       as Tasty
 import           Test.Tasty.HUnit                 (testCase, (@=?))
 import qualified Test.Tasty.Runners               as Tasty
-import           Test.Tasty.SmallCheck            (forAll, testProperty)
+import           Test.Tasty.QuickCheck            (forAll, testProperty,
+                                                   arbitrary)
 
 
 import           Control.Exception                (throwIO)
@@ -46,26 +47,26 @@
   [ testCase "fmap id Nothing = Nothing" $ do
       fmap id Nothing @=? (Nothing :: Maybe ())
   , testProperty "fmap id = id" $ do
-      forAll $ \(x :: [Int]) ->
+      forAll arbitrary $ \(x :: [Int]) ->
         fmap id x == id x
   , testCase "fmap (f . g) Nothing = (fmap f . fmap g) Nothing" $ do
       fmap (not . not) Nothing @=? (fmap not . fmap not) (Nothing :: Maybe Bool)
   , testProperty "fmap (f . g) = fmap f . fmap g" $ do
-      forAll $ \(x :: [Int]) ->
+      forAll arbitrary $ \(x :: [Int]) ->
         fmap (odd . succ) x == (fmap odd . fmap succ) x
   ]
 
--- Just an arbitrary type that can be generated by SmallCheck.
+-- Just an arbitrary type that can be generated by QuickCheck.
 type FunnyType = (String, (Double, (Int, (Maybe Int, Either Bool Int))))
 
 testPipesBinary :: Tasty.TestTree
 testPipesBinary = Tasty.testGroup "pipes-binary"
   [ testProperty "Pipes.Binary.encode ~ Data.Binary.encode" $ do
-      forAll $ \(x :: FunnyType) ->
+      forAll arbitrary $ \(x :: FunnyType) ->
          BL.toStrict (Bin.encode x) == B.concat (P.toList (PBin.encode x))
 
   , testProperty "Pipes.Binary.decodeL ~ Data.Binary.decode" $ do
-      forAll $ \(x :: FunnyType) ->
+      forAll arbitrary $ \(x :: FunnyType) ->
          let bl = Bin.encode x
              bs = BL.toStrict bl
              o1 = Bin.decodeOrFail bl
@@ -79,14 +80,14 @@
               _ -> False
 
   , testProperty "Pipes.Binary.decodeL ~ Pipes.Binary.decode" $ do
-      forAll $ \(x :: FunnyType) ->
+      forAll arbitrary $ \(x :: FunnyType) ->
          let bs = BL.toStrict $ Bin.encode x
              o1 = runIdentity $ evalStateT PBin.decodeL (yield bs)
              o2 = runIdentity $ evalStateT PBin.decode  (yield bs)
          in fmap snd o1 == (o2 :: Either PBin.DecodingError FunnyType)
 
   , testProperty "Pipes.Binary.decoded zoom" $ do
-      forAll $ \amx0 amx1 amx2 amx3 amx4 amx5 amx6 ->
+      forAll arbitrary $ \amx0 amx1 amx2 amx3 amx4 amx5 amx6 ->
          let xs :: [FunnyType] -- I get more tests cases this way.
              xs = [amx0, amx1, amx2, amx3, amx4, amx5, amx6] >>= maybe [] id
              dec0 :: Monad m => MaybeT (StateT (Producer B.ByteString m a) m) ()
