diff --git a/CHANGELOG.md b/CHANGELOG.md
new file mode 100644
--- /dev/null
+++ b/CHANGELOG.md
@@ -0,0 +1,16 @@
+
+0.0.0.1
+-------
+
+_Andreas Abel, 2022-06-10_
+
+- Support `base-4.17` which dropped `instance MonadFail ST`.
+- Tested with GHC 7.4 - 9.4.
+
+
+0.0.0.0
+-------
+
+_Herbert Valerio Riedel, 2019-04-20_
+
+Let there be light!
diff --git a/brotli.cabal b/brotli.cabal
--- a/brotli.cabal
+++ b/brotli.cabal
@@ -1,15 +1,15 @@
 cabal-version:       1.12
 build-type:          Simple
 name:                brotli
-version:             0.0.0.0
+version:             0.0.0.1
 
 synopsis:            Brotli (RFC7932) compression and decompression
-homepage:            https://github.com/hvr/brotli
-bug-reports:         https://github.com/hvr/brotli/issues
+homepage:            https://github.com/haskell-hvr/brotli
+bug-reports:         https://github.com/haskell-hvr/brotli/issues
 license:             GPL-3
 license-file:        LICENSE
 author:              Herbert Valerio Riedel
-maintainer:          hvr@gnu.org
+maintainer:          https://github.com/haskell-hvr/brotli
 copyright:           (c) 2016, Herbert Valerio Riedel
 category:            Codec, Compression
 description:
@@ -30,21 +30,38 @@
       * </package/brotli-conduit brotli-conduit> (for </package/conduit conduit>)
     .
 
+tested-with:
+  GHC == 9.4.1
+  GHC == 9.2.2
+  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
+  GHC == 7.10.3
+  GHC == 7.8.4
+  GHC == 7.6.3
+  GHC == 7.4.2
+
+
 extra-source-files:
+  CHANGELOG.md
   cbits/hs_brotli.h
 
 source-repository head
   type:     git
-  location: https://github.com/hvr/brotli.git
+  location: https://github.com/haskell-hvr/brotli.git
 
 library
   hs-source-dirs:      src
   exposed-modules:     Codec.Compression.Brotli
   other-modules:       LibBrotli
 
-  build-depends:       base         >=4.5     && <4.13
-                     , bytestring   >=0.9.2   && <0.11
-                     , transformers >=0.3.0.0 && <0.6
+  build-depends:       base         >=4.5     && <4.18
+                     , bytestring   >=0.9.2   && <0.12
+                     , transformers >=0.3.0.0 && <0.7
 
   default-language:    Haskell2010
 
@@ -54,6 +71,8 @@
   include-dirs:        cbits
 
   ghc-options:         -Wall
+  if impl(ghc >= 8.0)
+    ghc-options:       -Wcompat
 
 test-suite brotli-tests
   default-language:    Haskell2010
@@ -68,9 +87,11 @@
                      , bytestring
   -- additional dependencies that require version bounds
   build-depends:       HUnit                       == 1.6.*
-                     , QuickCheck                  == 2.13.*
-                     , tasty                       == 1.2.*
+                     , QuickCheck                  == 2.14.*
+                     , tasty                       >= 1.2     && < 1.5
                      , tasty-hunit                 == 0.10.*
                      , tasty-quickcheck            == 0.10.*
 
   ghc-options:         -Wall -threaded
+  if impl(ghc >= 8.0)
+    ghc-options:       -Wcompat
diff --git a/cbits/hs_brotli.h b/cbits/hs_brotli.h
--- a/cbits/hs_brotli.h
+++ b/cbits/hs_brotli.h
@@ -51,7 +51,7 @@
       }
   }
 
-  return HS_BS_INTERNAL_ERROR;  
+  return HS_BS_INTERNAL_ERROR;
 }
 
 static inline HsBrotliState
@@ -87,7 +87,7 @@
   *buf_out = (uint8_t*) BrotliEncoderTakeOutput(state, sizep);
 
   const size_t size = *sizep;
-  
+
   if (!*buf_out && size != 0) {
     *sizep = 0;
     return HS_BS_INTERNAL_ERROR;
@@ -100,7 +100,7 @@
     case BROTLI_TRUE: return HS_BS_FINISHED;
     case BROTLI_FALSE: return HS_BS_NEEDS_INPUT;
     }
-    return HS_BS_INTERNAL_ERROR;  
+    return HS_BS_INTERNAL_ERROR;
   }
 
   // non-empty
@@ -115,7 +115,7 @@
 
   *sizep = 0;
   *buf_out = NULL;
-  return HS_BS_INTERNAL_ERROR;  
+  return HS_BS_INTERNAL_ERROR;
 }
 
 static inline HsBrotliState
@@ -124,7 +124,7 @@
   *buf_out = (uint8_t*) BrotliDecoderTakeOutput(state, sizep);
 
   const size_t size = *sizep;
-  
+
   if (!*buf_out && size != 0) {
     *sizep = 0;
     return HS_BS_INTERNAL_ERROR;
@@ -137,7 +137,7 @@
     case BROTLI_TRUE: return HS_BS_FINISHED;
     case BROTLI_FALSE: return HS_BS_NEEDS_INPUT;
     }
-    return HS_BS_INTERNAL_ERROR;  
+    return HS_BS_INTERNAL_ERROR;
   }
 
   // non-empty
@@ -152,7 +152,7 @@
 
   *sizep = 0;
   *buf_out = NULL;
-  return HS_BS_INTERNAL_ERROR;  
+  return HS_BS_INTERNAL_ERROR;
 }
 
 static inline char*
diff --git a/src-tests/brotli-tests.hs b/src-tests/brotli-tests.hs
--- a/src-tests/brotli-tests.hs
+++ b/src-tests/brotli-tests.hs
@@ -3,17 +3,17 @@
 module Main (main) where
 
 import           Control.Applicative
-import qualified Data.ByteString as BS
-import qualified Data.ByteString.Lazy as BL
-import           Data.ByteString.Lazy.Char8 ()
-import           Data.List
+import qualified Data.ByteString             as BS
+import qualified Data.ByteString.Lazy        as BL
+import           Data.ByteString.Lazy.Char8  ()
+import           Data.List                   (intersperse)
 import           Prelude
 
 import           Test.Tasty
-import           Test.Tasty.QuickCheck as QC
+import           Test.Tasty.QuickCheck       as QC
 import           Test.Tasty.HUnit
 
-import           Codec.Compression.Brotli as Brotli
+import           Codec.Compression.Brotli    as Brotli
 
 main :: IO ()
 main = defaultMain tests
diff --git a/src/Codec/Compression/Brotli.hs b/src/Codec/Compression/Brotli.hs
--- a/src/Codec/Compression/Brotli.hs
+++ b/src/Codec/Compression/Brotli.hs
@@ -1,4 +1,5 @@
 {-# LANGUAGE BangPatterns       #-}
+{-# LANGUAGE CPP                #-}
 {-# LANGUAGE DeriveDataTypeable #-}
 {-# LANGUAGE Trustworthy        #-}
 
@@ -86,7 +87,9 @@
 import qualified Data.ByteString               as BS
 import qualified Data.ByteString.Lazy          as BSL
 import qualified Data.ByteString.Lazy.Internal as BSL
+#if !MIN_VERSION_base(4,8,0)
 import           Data.Monoid                   (Monoid (mempty))
+#endif
 import           Data.Typeable                 (Typeable)
 import           GHC.IO                        (noDuplicate)
 
@@ -267,7 +270,8 @@
 
         goFlush :: ST s (CompressStream (ST s))
         goFlush  = do
-            (rc, 0) <- strictToLazyST (noDuplicateST >> runBrotliEncoder ls mempty BrotliEncOpFlush)
+            (rc, n) <- strictToLazyST (noDuplicateST >> runBrotliEncoder ls mempty BrotliEncOpFlush)
+            unless (n == 0) internalError
             case rc of
                 BSFail          -> encoderFailure
                 BSInternalError -> internalError
@@ -277,7 +281,8 @@
 
         goFinish :: ST s (CompressStream (ST s))
         goFinish = do
-            (rc, 0) <- strictToLazyST (noDuplicateST >> runBrotliEncoder ls mempty BrotliEncOpFinish)
+            (rc, n) <- strictToLazyST (noDuplicateST >> runBrotliEncoder ls mempty BrotliEncOpFinish)
+            unless (n == 0) internalError
             case rc of
                 BSFail          -> encoderFailure
                 BSInternalError -> internalError
@@ -402,7 +407,8 @@
 
         goFinish :: ST s (DecompressStream (ST s))
         goFinish = do
-            (rc, ecode, 0) <- strictToLazyST (noDuplicateST >> runBrotliDecoder ls mempty)
+            (rc, ecode, n) <- strictToLazyST (noDuplicateST >> runBrotliDecoder ls mempty)
+            unless (n == 0) internalError
             case rc of
                 BSFail          -> pure (DecompressStreamError ecode)
                 BSInternalError -> internalError
diff --git a/src/LibBrotli.hsc b/src/LibBrotli.hsc
--- a/src/LibBrotli.hsc
+++ b/src/LibBrotli.hsc
@@ -49,9 +49,6 @@
 
 #include "hs_brotli.h"
 
-allocaPoke :: Storable x => x -> (Ptr x -> IO b) -> IO b
-allocaPoke v0 act = alloca $ \pv -> do { poke pv v0; act pv }
-
 packBS :: Ptr Word8 -> CSize -> IO ByteString
 packBS p sz
   | sz > 0    = BS.packCStringLen (castPtr p, fromIntegral sz)
@@ -228,9 +225,9 @@
 runBrotliEncoder (BrotliEncoder fp) ibs action0
   = unsafeIOToST $ withForeignPtr fp $ \encPtr -> do
       BS.unsafeUseAsCStringLen ibs $ \(ibsptr, ibslen) ->
-        allocaPoke (fromIntegral ibslen) $ \availIn ->
-          allocaPoke ibsptr $ \nextIn -> do
-            allocaPoke 0 $ \availOut -> do
+        with (fromIntegral ibslen) $ \availIn ->
+          with ibsptr $ \nextIn -> do
+            with 0 $ \availOut -> do
               rc <- fromHsBrotliState <$>
                     c_BrotliEncoderCompressStream encPtr action availIn (castPtr nextIn) availOut nullPtr nullPtr
               availIn' <- fromIntegral <$> peek availIn
@@ -247,9 +244,9 @@
 runBrotliDecoder (BrotliDecoder fp) ibs
   = unsafeIOToST $ withForeignPtr fp $ \encPtr -> do
       BS.unsafeUseAsCStringLen ibs $ \(ibsptr, ibslen) ->
-        allocaPoke (fromIntegral ibslen) $ \availIn ->
-          allocaPoke ibsptr $ \nextIn -> do
-            allocaPoke 0 $ \availOut -> do
+        with (fromIntegral ibslen) $ \availIn ->
+          with ibsptr $ \nextIn -> do
+            with 0 $ \availOut -> do
               rc <- fromHsBrotliState <$>
                     c_BrotliDecoderDecompressStream encPtr availIn (castPtr nextIn) availOut nullPtr nullPtr
               availIn' <- fromIntegral <$> peek availIn
@@ -261,7 +258,7 @@
 readBrotliEncoder :: BrotliEncoder -> Int {- max-output -} -> ST s (BrotliState, ByteString)
 readBrotliEncoder (BrotliEncoder fp) maxobs
   = unsafeIOToST $ withForeignPtr fp $ \encPtr -> do
-      allocaPoke (fromIntegral maxobs) $ \availOutPtr -> do
+      with (fromIntegral maxobs) $ \availOutPtr -> do
         alloca $ \obsptrptr -> do
           rc <- fromHsBrotliState <$>
                 c_BrotliEncoderTakeOutput encPtr availOutPtr obsptrptr
@@ -273,7 +270,7 @@
 readBrotliDecoder :: BrotliDecoder -> Int {- max-output -} -> ST s (BrotliState, ByteString)
 readBrotliDecoder (BrotliDecoder fp) maxobs
   = unsafeIOToST $ withForeignPtr fp $ \encPtr -> do
-      allocaPoke (fromIntegral maxobs) $ \availOutPtr -> do
+      with (fromIntegral maxobs) $ \availOutPtr -> do
         alloca $ \obsptrptr -> do
           rc <- fromHsBrotliState <$>
                 c_BrotliDecoderTakeOutput encPtr availOutPtr obsptrptr
