diff --git a/Data/Conduit/Blaze.hs b/Data/Conduit/Blaze.hs
new file mode 100644
--- /dev/null
+++ b/Data/Conduit/Blaze.hs
@@ -0,0 +1,114 @@
+{-# LANGUAGE FlexibleContexts #-}
+{-# LANGUAGE BangPatterns #-}
+-- | Convert a stream of blaze-builder @Builder@s into a stream of @ByteString@s.
+--
+-- Adapted from blaze-builder-enumerator, written by myself and Simon Meier.
+--
+-- Note that the functions here can work in any monad built on top of @IO@ or
+-- @ST@.
+module Data.Conduit.Blaze
+    (
+
+  -- * Buffers
+    Buffer
+
+  -- ** Status information
+  , freeSize
+  , sliceSize
+  , bufferSize
+
+  -- ** Creation and modification
+  , allocBuffer
+  , reuseBuffer
+  , nextSlice
+
+  -- ** Conversion to bytestings
+  , unsafeFreezeBuffer
+  , unsafeFreezeNonEmptyBuffer
+
+  -- * Buffer allocation strategies
+  , BufferAllocStrategy
+  , allNewBuffersStrategy
+  , reuseBufferStrategy
+
+  -- * Enumeratees from builders to bytestrings
+  , builderToByteString
+  , unsafeBuilderToByteString
+  , builderToByteStringWith
+
+    ) where
+
+import Data.Conduit hiding (SinkResult (Done))
+import Control.Monad.Trans.Resource
+import Control.Monad.Trans.Class
+
+import qualified Data.ByteString                   as S
+
+import Blaze.ByteString.Builder.Internal
+import Blaze.ByteString.Builder.Internal.Types
+import Blaze.ByteString.Builder.Internal.Buffer
+
+-- | Incrementally execute builders and pass on the filled chunks as
+-- bytestrings.
+builderToByteString :: ResourceUnsafeIO m => Conduit Builder m S.ByteString
+builderToByteString =
+  builderToByteStringWith (allNewBuffersStrategy defaultBufferSize)
+
+-- | Incrementally execute builders on the given buffer and pass on the filled
+-- chunks as bytestrings. Note that, if the given buffer is too small for the
+-- execution of a build step, a larger one will be allocated.
+--
+-- WARNING: This conduit yields bytestrings that are NOT
+-- referentially transparent. Their content will be overwritten as soon
+-- as control is returned from the inner sink!
+unsafeBuilderToByteString :: ResourceUnsafeIO m
+                          => IO Buffer  -- action yielding the inital buffer.
+                          -> Conduit Builder m S.ByteString
+unsafeBuilderToByteString = builderToByteStringWith . reuseBufferStrategy
+
+
+-- | A conduit that incrementally executes builders and passes on the
+-- filled chunks as bytestrings to an inner sink.
+--
+-- INV: All bytestrings passed to the inner sink are non-empty.
+builderToByteStringWith :: ResourceUnsafeIO m
+                        => BufferAllocStrategy
+                        -> Conduit Builder m S.ByteString
+builderToByteStringWith (ioBuf0, nextBuf) = conduitState
+    ioBuf0
+    push
+    close
+  where
+    finalStep !(BufRange pf _) = return $ Done pf ()
+
+    close ioBuf = lift $ unsafeFromIO $ do
+        buf <- ioBuf
+        return $ maybe [] return $ unsafeFreezeNonEmptyBuffer buf
+
+    push ioBuf x = lift $ unsafeFromIO $ do
+        (ioBuf', front) <- go (unBuilder x (buildStep finalStep)) ioBuf id
+        return (ioBuf', Producing $ front [])
+
+    go bStep ioBuf front = do
+        !buf   <- ioBuf
+        signal <- (execBuildStep bStep buf)
+        case signal of
+            Done op' _ -> return (return $ updateEndOfSlice buf op', front)
+            BufferFull minSize op' bStep' -> do
+                let buf' = updateEndOfSlice buf op'
+                    {-# INLINE cont #-}
+                    cont front' = do
+                        -- sequencing the computation of the next buffer
+                        -- construction here ensures that the reference to the
+                        -- foreign pointer `fp` is lost as soon as possible.
+                        ioBuf' <- nextBuf minSize buf'
+                        go bStep' ioBuf' front'
+                case unsafeFreezeNonEmptyBuffer buf' of
+                    Nothing -> cont front
+                    Just bs -> cont (front . (bs:))
+            InsertByteString op' bs bStep' -> do
+                let buf' = updateEndOfSlice buf op'
+                    bsk  = maybe id (:) $ unsafeFreezeNonEmptyBuffer buf'
+                    front' = front . bsk . (bs:)
+                ioBuf' <- nextBuf 1 buf'
+                go bStep' ioBuf' front'
diff --git a/LICENSE b/LICENSE
new file mode 100644
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,30 @@
+Copyright (c)2011, Michael Snoyman
+
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+    * Redistributions of source code must retain the above copyright
+      notice, this list of conditions and the following disclaimer.
+
+    * Redistributions in binary form must reproduce the above
+      copyright notice, this list of conditions and the following
+      disclaimer in the documentation and/or other materials provided
+      with the distribution.
+
+    * Neither the name of Michael Snoyman nor the names of other
+      contributors may be used to endorse or promote products derived
+      from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/Setup.lhs b/Setup.lhs
new file mode 100644
--- /dev/null
+++ b/Setup.lhs
@@ -0,0 +1,7 @@
+#!/usr/bin/env runhaskell
+
+> module Main where
+> import Distribution.Simple
+
+> main :: IO ()
+> main = defaultMain
diff --git a/blaze-builder-conduit.cabal b/blaze-builder-conduit.cabal
new file mode 100644
--- /dev/null
+++ b/blaze-builder-conduit.cabal
@@ -0,0 +1,44 @@
+Name:                blaze-builder-conduit
+Version:             0.0.0
+Synopsis:            Convert streams of builders to streams of bytestrings.
+Description:         Convert streams of builders to streams of bytestrings.
+License:             BSD3
+License-file:        LICENSE
+Author:              Michael Snoyman
+Maintainer:          michael@snoyman.com
+Category:            Data, Conduit
+Build-type:          Simple
+Cabal-version:       >=1.8
+Homepage:            http://github.com/snoyberg/conduit
+extra-source-files:  test/main.hs
+
+Library
+  Exposed-modules:     Data.Conduit.Blaze
+  Build-depends:       base                     >= 4            && < 5
+                     , containers
+                     , transformers             >= 0.2.2        && < 0.3
+                     , bytestring               >= 0.9
+                     , text                     >= 0.11
+                     , blaze-builder            >= 0.2.1.4      && < 0.4
+                     , conduit                  >= 0.0          && < 0.1
+  ghc-options:     -Wall
+
+test-suite test
+    hs-source-dirs: test
+    main-is: main.hs
+    type: exitcode-stdio-1.0
+    cpp-options:   -DTEST
+    build-depends:   conduit
+                   , base
+                   , hspec
+                   , HUnit
+                   , QuickCheck
+                   , bytestring
+                   , blaze-builder
+                   , blaze-builder-conduit
+                   , transformers
+    ghc-options:     -Wall
+
+source-repository head
+  type:     git
+  location: git://github.com/snoyberg/conduit.git
diff --git a/test/main.hs b/test/main.hs
new file mode 100644
--- /dev/null
+++ b/test/main.hs
@@ -0,0 +1,44 @@
+{-# LANGUAGE OverloadedStrings #-}
+{-# LANGUAGE CPP #-}
+import Test.Hspec.Monadic
+import Test.Hspec.HUnit ()
+import Test.Hspec.QuickCheck (prop)
+import Test.HUnit
+
+import qualified Data.Conduit as C
+import qualified Data.Conduit.List as CL
+import Data.ByteString.Char8 ()
+import Data.Conduit.Blaze (builderToByteString)
+import Data.Conduit (runResourceT)
+import Control.Monad.ST (runST)
+import Data.Monoid
+import qualified Data.ByteString as S
+import Blaze.ByteString.Builder (fromByteString, toLazyByteString, insertLazyByteString)
+import qualified Data.ByteString.Lazy as L
+import Data.ByteString.Lazy.Char8 ()
+import Control.Monad.IO.Class (liftIO)
+
+main :: IO ()
+main = hspecX $ do
+    describe "blaze" $ do
+        prop "idempotent to toLazyByteString" $ \bss' -> runST $ runResourceT $ do
+            let bss = map S.pack bss'
+            let builders = map fromByteString bss
+            let lbs = toLazyByteString $ mconcat builders
+            let src = mconcat $ map (CL.sourceList . return) builders
+            outBss <- src C.$= builderToByteString C.$$ CL.consume
+            return $ lbs == L.fromChunks outBss
+
+        it "works for large input" $ runResourceT $ do
+            let builders = replicate 10000 (fromByteString "hello world!")
+            let lbs = toLazyByteString $ mconcat builders
+            let src = mconcat $ map (CL.sourceList . return) builders
+            outBss <- src C.$= builderToByteString C.$$ CL.consume :: C.ResourceT IO [S.ByteString]
+            liftIO $ lbs @=? L.fromChunks outBss
+
+        it "works for lazy bytestring insertion" $ runResourceT $ do
+            let builders = replicate 10000 (insertLazyByteString "hello world!")
+            let lbs = toLazyByteString $ mconcat builders
+            let src = mconcat $ map (CL.sourceList . return) builders
+            outBss <- src C.$= builderToByteString C.$$ CL.consume :: C.ResourceT IO [S.ByteString]
+            liftIO $ lbs @=? L.fromChunks outBss
