diff --git a/ChangeLog.md b/ChangeLog.md
--- a/ChangeLog.md
+++ b/ChangeLog.md
@@ -1,3 +1,7 @@
+## 3.2.1.2
+
+* Remove dependency on blaze-builder [#683](https://github.com/yesodweb/wai/pull/683)
+
 ## 3.2.1.1
 
 * Relax upper bound on bytestring-builder
diff --git a/Network/Wai.hs b/Network/Wai.hs
--- a/Network/Wai.hs
+++ b/Network/Wai.hs
@@ -1,13 +1,11 @@
-{-# LANGUAGE Rank2Types #-}
-{-# LANGUAGE CPP #-}
 {-|
 
 This module defines a generic web application interface. It is a common
 protocol between web servers and web applications.
 
 The overriding design principles here are performance and generality. To
-address performance, this library is built on top of the conduit and
-blaze-builder packages.  The advantages of conduits over lazy IO have been
+address performance, this library is built on top of the conduit package and
+bytestring's Builder type.  The advantages of conduits over lazy IO have been
 debated elsewhere and so will not be addressed here.  However, helper functions
 like 'responseLBS' allow you to continue using lazy IO if you so desire.
 
@@ -85,8 +83,8 @@
     , modifyResponse
     ) where
 
-import           Blaze.ByteString.Builder     (Builder, fromLazyByteString)
-import           Blaze.ByteString.Builder     (fromByteString)
+import           Data.ByteString.Builder      (Builder, lazyByteString)
+import           Data.ByteString.Builder      (byteString)
 import           Control.Monad                (unless)
 import qualified Data.ByteString              as B
 import qualified Data.ByteString.Lazy         as L
@@ -94,7 +92,6 @@
 import           Data.ByteString.Lazy.Internal (defaultChunkSize)
 import           Data.ByteString.Lazy.Char8   ()
 import           Data.Function                (fix)
-import           Data.Monoid                  (mempty)
 import qualified Network.HTTP.Types           as H
 import           Network.Socket               (SockAddr (SockAddrInet))
 import           Network.Wai.Internal
@@ -122,13 +119,13 @@
 --
 -- A2. No. If the ByteStrings are small, then they will be copied into a larger
 -- buffer, which should be a performance gain overall (less system calls). If
--- they are already large, then blaze-builder uses an InsertByteString
--- instruction to avoid copying.
+-- they are already large, then an insert operation is used
+-- to avoid copying.
 --
 -- Q3. Doesn't this prevent us from creating comet-style servers, since data
 -- will be cached?
 --
--- A3. You can force blaze-builder to output a ByteString before it is an
+-- A3. You can force a Builder to output a ByteString before it is an
 -- optimal size by sending a flush command.
 responseBuilder :: H.Status -> H.ResponseHeaders -> Builder -> Response
 responseBuilder = ResponseBuilder
@@ -136,7 +133,7 @@
 -- | Creating 'Response' from 'L.ByteString'. This is a wrapper for
 --   'responseBuilder'.
 responseLBS :: H.Status -> H.ResponseHeaders -> L.ByteString -> Response
-responseLBS s h = ResponseBuilder s h . fromLazyByteString
+responseLBS s h = ResponseBuilder s h . lazyByteString
 
 -- | Creating 'Response' from a stream of values.
 --
@@ -150,9 +147,9 @@
 --     (putStrLn \"Allocating scarce resource\")
 --     (putStrLn \"Cleaning up\")
 --     $ respond $ responseStream status200 [] $ \\write flush -> do
---         write $ fromByteString \"Hello\\n\"
+--         write $ byteString \"Hello\\n\"
 --         flush
---         write $ fromByteString \"World\\n\"
+--         write $ byteString \"World\\n\"
 -- @
 --
 -- Note that in some cases you can use @bracket@ from inside @responseStream@
@@ -215,7 +212,7 @@
                 bs <- B.hGetSome handle defaultChunkSize
                 unless (B.null bs) $ do
                     let x = B.take remaining bs
-                    sendChunk $ fromByteString x
+                    sendChunk $ byteString x
                     loop $ remaining - B.length x
         loop $ fromIntegral $ filePartByteCount part
     )
@@ -226,7 +223,7 @@
        withBody $ \sendChunk _flush -> fix $ \loop -> do
             bs <- B.hGetSome handle defaultChunkSize
             unless (B.null bs) $ do
-                sendChunk $ fromByteString bs
+                sendChunk $ byteString bs
                 loop
     )
 responseToStream (ResponseBuilder s h b) =
diff --git a/Network/Wai/Internal.hs b/Network/Wai/Internal.hs
--- a/Network/Wai/Internal.hs
+++ b/Network/Wai/Internal.hs
@@ -1,17 +1,12 @@
 {-# OPTIONS_HADDOCK not-home #-}
-{-# LANGUAGE DeriveDataTypeable #-}
 {-# LANGUAGE CPP #-}
-{-# LANGUAGE RankNTypes #-}
 {-# LANGUAGE RecordWildCards #-}
 -- | Internal constructors and helper functions. Note that no guarantees are
 -- given for stability of these interfaces.
 module Network.Wai.Internal where
 
-import           Blaze.ByteString.Builder     (Builder)
+import           Data.ByteString.Builder      (Builder)
 import qualified Data.ByteString              as B hiding (pack)
-#if __GLASGOW_HASKELL__ < 709
-import           Data.Functor                 ((<$>))
-#endif
 import           Data.Text                    (Text)
 import           Data.Typeable                (Typeable)
 import           Data.Vault.Lazy              (Vault)
diff --git a/README.md b/README.md
--- a/README.md
+++ b/README.md
@@ -67,7 +67,7 @@
 An `Application` maps `Request`s to `Response`s:
 
     ghci> :info  Application
-    type Application = Request -> IO Response
+    type Application = Request -> (Response -> IO ResponseReceived) -> IO ResponseReceived
 
 Depending on the path info provided with each `Request` we can serve different `Response`s:
 
diff --git a/test/Network/WaiSpec.hs b/test/Network/WaiSpec.hs
--- a/test/Network/WaiSpec.hs
+++ b/test/Network/WaiSpec.hs
@@ -3,12 +3,10 @@
 import Test.Hspec
 import Test.Hspec.QuickCheck (prop)
 import Network.Wai
-import Network.Wai.Internal (Request (Request))
 import Data.IORef
-import Data.Monoid
 import qualified Data.ByteString as S
 import qualified Data.ByteString.Lazy as L
-import Blaze.ByteString.Builder (toByteString, Builder, fromWord8)
+import Data.ByteString.Builder (Builder, toLazyByteString, word8)
 import Control.Monad (forM_)
 
 spec :: Spec
@@ -24,17 +22,17 @@
                         flush :: IO ()
                         flush = return ()
                     streamingBody add flush
-                    fmap toByteString $ readIORef builderRef
+                    fmap (L.toStrict . toLazyByteString) $ readIORef builderRef
         prop "responseLBS" $ \bytes -> do
             body <- getBody $ responseLBS undefined undefined $ L.pack bytes
             body `shouldBe` S.pack bytes
         prop "responseBuilder" $ \bytes -> do
             body <- getBody $ responseBuilder undefined undefined
-                            $ mconcat $ map fromWord8 bytes
+                            $ mconcat $ map word8 bytes
             body `shouldBe` S.pack bytes
         prop "responseStream" $ \chunks -> do
             body <- getBody $ responseStream undefined undefined $ \sendChunk _ ->
-                forM_ chunks $ \chunk -> sendChunk $ mconcat $ map fromWord8 chunk
+                forM_ chunks $ \chunk -> sendChunk $ mconcat $ map word8 chunk
             body `shouldBe` S.concat (map S.pack chunks)
         it "responseFile total" $ do
             let fp = "wai.cabal"
@@ -57,7 +55,7 @@
     describe "lazyRequestBody" $ do
         prop "works" $ \chunks -> do
             ref <- newIORef $ map S.pack $ filter (not . null) chunks
-            let req = Request
+            let req = defaultRequest
                         { requestBody = atomicModifyIORef ref $ \bss ->
                             case bss of
                                 [] -> ([], S.empty)
@@ -66,7 +64,7 @@
             body <- lazyRequestBody req
             body `shouldBe` L.fromChunks (map S.pack chunks)
         it "is lazy" $ do
-            let req = Request
+            let req = defaultRequest
                         { requestBody = error "requestBody"
                         }
             _ <- lazyRequestBody req
@@ -74,7 +72,7 @@
     describe "strictRequestBody" $ do
         prop "works" $ \chunks -> do
             ref <- newIORef $ map S.pack $ filter (not . null) chunks
-            let req = Request
+            let req = defaultRequest
                         { requestBody = atomicModifyIORef ref $ \bss ->
                             case bss of
                                 [] -> ([], S.empty)
diff --git a/wai.cabal b/wai.cabal
--- a/wai.cabal
+++ b/wai.cabal
@@ -1,8 +1,9 @@
 Name:                wai
-Version:             3.2.1.1
+Version:             3.2.1.2
 Synopsis:            Web Application Interface.
 Description:         Provides a common protocol for communication between web applications and web servers.
-description:         API docs and the README are available at <http://www.stackage.org/package/wai>.
+                     .
+                     API docs and the README are available at <http://www.stackage.org/package/wai>.
 License:             MIT
 License-file:        LICENSE
 Author:              Michael Snoyman
@@ -19,10 +20,8 @@
     location:        git://github.com/yesodweb/wai.git
 
 Library
-  Build-Depends:     base                      >= 4        && < 5
-                   , bytestring                >= 0.10
-                   , bytestring-builder        >= 0.10.4.0 && < 0.11
-                   , blaze-builder             >= 0.2.1.4  && < 0.5
+  Build-Depends:     base                      >= 4.8      && < 5
+                   , bytestring                >= 0.10.4
                    , network                   >= 2.2.1.5
                    , http-types                >= 0.7
                    , text                      >= 0.7
@@ -36,14 +35,14 @@
     hs-source-dirs: test
     main-is:        Spec.hs
     type:           exitcode-stdio-1.0
-    ghc-options:    -threaded
+    ghc-options:    -threaded -Wall
     cpp-options:    -DTEST
-    build-depends:  base
+    build-depends:  base >= 4.8 && < 5
                   , wai
                   , hspec
-                  , blaze-builder
                   , bytestring
     other-modules:  Network.WaiSpec
+    build-tool-depends: hspec-discover:hspec-discover
 
 source-repository head
   type:     git
