diff --git a/Data/Conduit/Zlib.hs b/Data/Conduit/Zlib.hs
new file mode 100644
--- /dev/null
+++ b/Data/Conduit/Zlib.hs
@@ -0,0 +1,73 @@
+{-# LANGUAGE FlexibleContexts #-}
+-- | Streaming compression and decompression using conduits.
+--
+-- Parts of this code were taken from zlib-enum and adapted for conduits.
+module Data.Conduit.Zlib (
+    -- * Conduits
+    compress, decompress, gzip, ungzip,
+    -- * Re-exported from zlib-bindings
+    WindowBits (..), defaultWindowBits
+) where
+
+import Codec.Zlib
+import Data.Conduit
+import Data.ByteString (ByteString)
+import qualified Data.ByteString as S
+import Control.Monad.Trans.Resource
+import Control.Monad.Trans.Class
+
+-- | Gzip compression with default parameters.
+gzip :: ResourceUnsafeIO m => Conduit ByteString m ByteString
+gzip = compress 1 (WindowBits 31)
+
+-- | Gzip decompression with default parameters.
+ungzip :: ResourceUnsafeIO m => Conduit ByteString m ByteString
+ungzip = decompress (WindowBits 31)
+
+-- |
+-- Decompress (inflate) a stream of 'ByteString's. For example:
+--
+-- >    sourceFile "test.z" $= decompress defaultWindowBits $$ sinkFile "test"
+
+decompress
+    :: ResourceUnsafeIO m
+    => WindowBits -- ^ Zlib parameter (see the zlib-bindings package as well as the zlib C library)
+    -> Conduit ByteString m ByteString
+decompress config = Conduit $ do
+    inf <- lift $ unsafeFromIO $ initInflate config
+    return $ PreparedConduit (push inf) (close inf)
+  where
+    push inf x = do
+        chunks <- lift $ unsafeFromIO $ withInflateInput inf x callback
+        return $ Producing chunks
+    close inf = do
+        chunk <- lift $ unsafeFromIO $ finishInflate inf
+        return $ if S.null chunk then [] else [chunk]
+
+-- |
+-- Compress (deflate) a stream of 'ByteString's. The 'WindowBits' also control
+-- the format (zlib vs. gzip).
+
+compress
+    :: ResourceUnsafeIO m
+    => Int         -- ^ Compression level
+    -> WindowBits  -- ^ Zlib parameter (see the zlib-bindings package as well as the zlib C library)
+    -> Conduit ByteString m ByteString
+compress level config = Conduit $ do
+    def <- lift $ unsafeFromIO $ initDeflate level config
+    return $ PreparedConduit (push def) (close def)
+  where
+    push def x = do
+        chunks <- lift $ unsafeFromIO $ withDeflateInput def x callback
+        return $ Producing chunks
+    close def = do
+        chunks <- lift $ unsafeFromIO $ finishDeflate def callback
+        return chunks
+
+callback :: Monad m => m (Maybe a) -> m [a]
+callback pop = go id where
+    go front = do
+       x <- pop
+       case x of
+           Nothing -> return $ front []
+           Just y -> go (front . (:) y)
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/test/main.hs b/test/main.hs
new file mode 100644
--- /dev/null
+++ b/test/main.hs
@@ -0,0 +1,25 @@
+{-# LANGUAGE OverloadedStrings #-}
+{-# LANGUAGE CPP #-}
+import Test.Hspec.Monadic
+import Test.Hspec.HUnit ()
+import Test.Hspec.QuickCheck (prop)
+
+import qualified Data.Conduit as C
+import qualified Data.Conduit.List as CL
+import qualified Data.Conduit.Zlib as CZ
+import Data.Conduit (runResourceT)
+import Control.Monad.ST (runST)
+import Data.Monoid
+import qualified Data.ByteString as S
+import qualified Data.ByteString.Lazy as L
+import Data.ByteString.Lazy.Char8 ()
+
+main :: IO ()
+main = hspecX $ do
+    describe "zlib" $ do
+        prop "idempotent" $ \bss' -> runST $ runResourceT $ do
+            let bss = map S.pack bss'
+                lbs = L.fromChunks bss
+                src = mconcat $ map (CL.sourceList . return) bss
+            outBss <- src C.$= CZ.gzip C.$= CZ.ungzip C.$$ CL.consume
+            return $ lbs == L.fromChunks outBss
diff --git a/zlib-conduit.cabal b/zlib-conduit.cabal
new file mode 100644
--- /dev/null
+++ b/zlib-conduit.cabal
@@ -0,0 +1,44 @@
+Name:                zlib-conduit
+Version:             0.0.0
+Synopsis:            Streaming compression/decompression via conduits.
+Description:         Streaming compression/decompression via conduits.
+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
+
+flag debug
+
+Library
+  Exposed-modules:     Data.Conduit.Zlib
+  Build-depends:       base                     >= 4            && < 5
+                     , containers
+                     , transformers             >= 0.2.2        && < 0.3
+                     , bytestring               >= 0.9
+                     , zlib-bindings            >= 0.0.1        && < 0.1
+                     , 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
+                   , transformers
+                   , zlib-conduit
+    ghc-options:     -Wall
+
+source-repository head
+  type:     git
+  location: git://github.com/snoyberg/conduit.git
