diff --git a/CHANGELOG.md b/CHANGELOG.md
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,36 @@
+# streaming-bytestring
+
+## 0.3.4 (2025-02-11)
+
+#### Changed
+
+- Ensure support for GHC 9.12.
+
+## 0.3.3 (2024-10-01)
+
+#### Fixed
+
+- A subtle bug involving conversion to lazy bytestrings.
+
+## 0.3.2 (2023-11-17)
+
+#### Changed
+
+- Ensure support for GHC 9.8.
+
+## 0.3.1 (2023-06-28)
+
+#### Changed
+
+- Ensure support for GHC 9.6.
+
+## 0.3.0 (2023-04-24)
+
+#### Changed
+
+- Dropped support for GHC 7.
+- Tightened PVP version bounds, for GHC 8.0 through to GHC 9.4.4.
+
 ## 0.2.4 (2022-08-26)
 
 #### Changed
diff --git a/lib/Streaming/ByteString.hs b/lib/Streaming/ByteString.hs
--- a/lib/Streaming/ByteString.hs
+++ b/lib/Streaming/ByteString.hs
@@ -189,11 +189,11 @@
     elem, filter, foldl, foldl1, foldr, foldr1, getContents, getLine, head,
     init, interact, iterate, last, length, lines, map, maximum, minimum,
     notElem, null, putStr, putStrLn, readFile, repeat, replicate, reverse,
-    scanl, scanl1, scanr, scanr1, span, splitAt, tail, take, takeWhile,
-    unlines, unzip, writeFile, zip, zipWith)
+    scanl, scanl1, scanr, scanr1, span, splitAt, tail, take, takeWhile, unlines,
+    unzip, writeFile, zip, zipWith)
 
-import qualified Data.ByteString as P (ByteString)
 import qualified Data.ByteString as B
+import qualified Data.ByteString as P (ByteString)
 import           Data.ByteString.Builder.Internal hiding
     (append, defaultChunkSize, empty, hPut)
 import qualified Data.ByteString.Internal as B
@@ -212,8 +212,8 @@
 import           Data.Word (Word8)
 import           Foreign.Ptr
 import           Foreign.Storable
-import           System.IO (Handle, IOMode(..), hClose, openBinaryFile)
 import qualified System.IO as IO (stdin, stdout)
+import           System.IO (Handle, IOMode(..), hClose, openBinaryFile)
 import           System.IO.Error (illegalOperationErrorType, mkIOError)
 
 -- | /O(n)/ Concatenate a stream of byte streams.
@@ -329,10 +329,10 @@
 {-# INLINE fromLazy #-}
 
 -- | /O(n)/ Convert an effectful byte stream into a single lazy 'ByteStream'
--- with the same internal chunk structure. See `toLazy` which preserve
--- connectedness by keeping the return value of the effectful bytestring.
+-- with the same internal chunk structure. See `toLazy` which preserves
+-- connectness by keeping the return value of the effectful bytestring.
 toLazy_ :: Monad m => ByteStream m r -> m BI.ByteString
-toLazy_ bs = dematerialize bs (\_ -> return BI.Empty) (fmap . BI.Chunk) join
+toLazy_ bs = dematerialize bs (\_ -> return BI.Empty) (fmap . BI.chunk) join
 {-# INLINE toLazy_ #-}
 
 -- | /O(n)/ Convert an effectful byte stream into a single lazy 'ByteString'
@@ -357,7 +357,7 @@
                 (\r -> return (BI.Empty :> r))
                 (\b mx -> do
                       (bs :> x) <- mx
-                      return $ BI.Chunk b bs :> x
+                      return $ BI.chunk b bs :> x
                       )
                 join
 {-# INLINE toLazy #-}
@@ -649,9 +649,9 @@
 -- @since 0.2.3
 for :: Monad m => ByteStream m r -> (P.ByteString -> ByteStream m x) -> ByteStream m r
 for stream f = case stream of
-  Empty r -> Empty r
+  Empty r      -> Empty r
   Chunk bs bss -> f bs *> for bss f
-  Go m -> Go ((`for` f) <$> m)
+  Go m         -> Go ((`for` f) <$> m)
 {-# INLINE for #-}
 
 -- -- | /O(n)/ 'reverse' @xs@ returns the elements of @xs@ in reverse order.
@@ -1343,9 +1343,9 @@
 concatBuilders :: Stream (Of Builder) IO () -> Builder
 concatBuilders p = builder $ \bstep r -> do
   case p of
-    Return _          -> runBuilderWith mempty bstep r
-    Step (b :> rest)  -> runBuilderWith (b `mappend` concatBuilders rest) bstep r
-    Effect m          -> m >>= \p' -> runBuilderWith (concatBuilders p') bstep r
+    Return _         -> runBuilderWith mempty bstep r
+    Step (b :> rest) -> runBuilderWith (b `mappend` concatBuilders rest) bstep r
+    Effect m         -> m >>= \p' -> runBuilderWith (concatBuilders p') bstep r
 {-# INLINABLE concatBuilders #-}
 
 -- | A simple construction of a builder from a 'ByteString'.
diff --git a/lib/Streaming/ByteString/Internal.hs b/lib/Streaming/ByteString/Internal.hs
--- a/lib/Streaming/ByteString/Internal.hs
+++ b/lib/Streaming/ByteString/Internal.hs
@@ -5,6 +5,7 @@
 {-# LANGUAGE MagicHash             #-}
 {-# LANGUAGE MultiParamTypeClasses #-}
 {-# LANGUAGE RankNTypes            #-}
+{-# LANGUAGE TypeOperators         #-}
 {-# LANGUAGE UnboxedTuples         #-}
 {-# LANGUAGE UndecidableInstances  #-}
 {-# LANGUAGE UnliftedFFITypes      #-}
diff --git a/streaming-bytestring.cabal b/streaming-bytestring.cabal
--- a/streaming-bytestring.cabal
+++ b/streaming-bytestring.cabal
@@ -1,6 +1,6 @@
 cabal-version:      >=1.10
 name:               streaming-bytestring
-version:            0.2.4
+version:            0.3.4
 synopsis:           Fast, effectful byte streams.
 description:
   This library enables fast and safe streaming of byte data, in either @Word8@ or
@@ -34,14 +34,17 @@
   https://github.com/haskell-streaming/streaming-bytestring/issues
 
 tested-with:
-  GHC ==7.10.3
-   || ==8.0.2
+  GHC ==8.0.2
    || ==8.2.2
    || ==8.4.4
    || ==8.6.5
    || ==8.8.4
    || ==8.10.3
    || ==9.0.2
+   || ==9.2.8
+   || ==9.4.8
+   || ==9.6.6
+   || ==9.8.4
 
 source-repository head
   type:     git
@@ -68,32 +71,21 @@
     Unsafe
 
   build-depends:
-      base               >=4.8     && <5.0
-    , bytestring
-    , deepseq
-    , exceptions
-    , ghc-prim           >=0.4     && <0.9
+      base               >=4.9     && <5.0
+    , bytestring         >=0.10.4  && <0.13
+    , deepseq            >=1.4     && <1.6
+    , exceptions         >=0.8     && <0.11
+    , ghc-prim           >=0.4     && <0.14
     , mmorph             >=1.0     && <1.3
-    , mtl                >=2.1     && <2.3
-    , resourcet
+    , mtl                >=2.2     && <2.4
+    , resourcet          >=1.1     && <1.4
     , streaming          >=0.1.4.0 && <0.3
-    , transformers       >=0.3     && <0.6
-    , transformers-base
-
-  if impl(ghc <7.8)
-    build-depends:
-        bytestring          >=0 && <0.10.4.0
-      , bytestring-builder
-
-  else
-    if impl(ghc <8.0)
-      build-depends: bytestring >=0.10.4 && <0.11
-
-    else
-      build-depends: bytestring >=0.10.4 && <0.12
+    , transformers       >=0.4     && <0.7
+    , transformers-base  >=0.4     && <0.5
 
   if impl(ghc <8.0)
-    build-depends: semigroups
+    build-depends:
+      semigroups         >=0.18    && <0.19
 
 test-suite test
   default-language: Haskell2010
@@ -101,13 +93,13 @@
   hs-source-dirs:   tests
   main-is:          Test.hs
   build-depends:
-      base                  >=4        && <5
-    , bytestring
-    , resourcet             >=1.1
+      base                  >=4.9     && <5
+    , bytestring            >=0.10.4  && <0.13
+    , resourcet             >=1.1     && <1.4
     , smallcheck            >=1.1.1
-    , streaming
+    , streaming             >=0.1.4.0 && <0.3
     , streaming-bytestring
     , tasty                 >=0.11.0.4
     , tasty-hunit           >=0.9
     , tasty-smallcheck      >=0.8.1
-    , transformers
+    , transformers          >=0.3     && <0.7
diff --git a/tests/Test.hs b/tests/Test.hs
--- a/tests/Test.hs
+++ b/tests/Test.hs
@@ -5,6 +5,7 @@
 
 import           Control.Monad.Trans.Resource (runResourceT)
 import qualified Data.ByteString.Char8 as B
+import qualified Data.ByteString.Lazy
 import qualified Data.ByteString.Lazy.Char8 as BL
 import           Data.Function (on)
 import           Data.Functor.Compose (Compose(..))
@@ -12,8 +13,8 @@
 import qualified Data.IORef as IOR
 import qualified Data.List as L
 import           Data.String (fromString)
-import           Streaming (Of(..))
 import qualified Streaming as SM
+import           Streaming (Of(..))
 import qualified Streaming.ByteString as Q
 import qualified Streaming.ByteString.Char8 as Q8
 import qualified Streaming.ByteString.Internal as QI
@@ -118,6 +119,11 @@
     $ Q8.readFile "tests/groupBy.txt"  -- ByteStream IO ()
   l @?= 57
 
+emptyChunks :: Assertion
+emptyChunks = do
+  bs <- Q.toLazy_ $ QI.chunkMap (const mempty) "bar"
+  assertBool "Expected empty chunks" $ Data.ByteString.Lazy.null bs
+
 readIntCases :: Assertion
 readIntCases = do
   let imax = maxBound :: Int
@@ -384,5 +390,6 @@
     , testCase "findIndexOrEnd" goodFindIndex
     , testCase "Stream Interop" firstI
     , testCase "readInt" readIntCases
+    , testCase "toLazy_: empty chunks" emptyChunks
     ]
   ]
