diff --git a/CHANGELOG.md b/CHANGELOG.md
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,10 @@
+# streaming-bytestring
+
+## 0.3.3 (2024-10-01)
+
+#### Fixed
+
+- A subtle bug involving conversion to lazy bytestrings.
 
 ## 0.3.2 (2023-11-17)
 
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/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.3.2
+version:            0.3.3
 synopsis:           Fast, effectful byte streams.
 description:
   This library enables fast and safe streaming of byte data, in either @Word8@ or
@@ -41,9 +41,9 @@
    || ==8.8.4
    || ==8.10.3
    || ==9.0.2
-   || ==9.2.7
-   || ==9.4.7
-   || ==9.6.3
+   || ==9.2.8
+   || ==9.4.8
+   || ==9.6.6
 
 source-repository head
   type:     git
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
     ]
   ]
