diff --git a/LICENSE b/LICENSE
new file mode 100644
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,26 @@
+Copyright (c) 2014-2015, Vertigo Media Inc. 
+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.
+
+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,3 @@
+#!/usr/bin/env runhaskell
+> import Distribution.Simple
+> main = defaultMain
diff --git a/io-streams-http.cabal b/io-streams-http.cabal
new file mode 100644
--- /dev/null
+++ b/io-streams-http.cabal
@@ -0,0 +1,28 @@
+name:                io-streams-http
+version:             0.1.0.0
+synopsis:            http-client for io-streams
+description:         Thin io-streams wrapper for http-client
+license:             BSD3
+license-file:        LICENSE
+author:              David Johnson
+maintainer:          djohnson.m@gmail.com
+copyright:           Vertigo Media Inc. 2014-2015 (c)
+category:            Web
+build-type:          Simple
+cabal-version:       >=1.10
+
+library
+  exposed-modules:     System.IO.Streams.HTTP
+  hs-source-dirs:      src
+  build-depends:       base >=4.7 && <4.8
+                     , bytestring
+                     , http-client
+                     , http-client-tls
+                     , io-streams
+                     , mtl
+                     , transformers >= 0.4.2.0
+  default-language:    Haskell2010
+
+source-repository head
+  type:     git
+  location: https://github.com/vertigomedia/io-streams-http.git
diff --git a/src/System/IO/Streams/HTTP.hs b/src/System/IO/Streams/HTTP.hs
new file mode 100644
--- /dev/null
+++ b/src/System/IO/Streams/HTTP.hs
@@ -0,0 +1,130 @@
+-- | Here is an example GET request that streams the response body to standard
+--   output:
+--
+-- > import           System.IO.Streams (InputStream, OutputStream)
+-- > import qualified System.IO.Streams as Streams
+-- > import           System.IO.Streams.HTTP
+-- > import           Network.HTTP.Client
+-- >
+-- > main :: IO ()
+-- > main = do
+-- >   req <- parseUrl "http://google.com"
+-- >   withManager defaultManagerSettings $ \m -> 
+-- >     withHTTP req m $ \resp -> do
+-- >       Streams.handleToOutputStream stdout >>=
+-- >         Streams.connect (responseBody resp)
+--
+--   Here is an example POST request that also streams the request
+--   body from
+--   standard input:
+--
+-- > {-# LANGUAGE OverloadedStrings #-}
+-- >
+-- > import           System.IO.Streams (InputStream, OutputStream)
+-- > import qualified System.IO.Streams as Streams
+-- > import           System.IO.Streams.HTTP
+-- > import           Network.HTTP.Client
+-- >
+-- > main :: IO ()
+-- > main = do
+-- >     req <- parseUrl "https://www.example.com"
+-- >     is <- handleFromInputStream stdin
+-- >     let req' = req
+-- >             { method = "POST"
+-- >             , requestBody = stream is
+-- >             }
+-- >     withManager tlsManagerSettings $ \m ->
+-- >       Streams.handleToOutputStream stdout >>=
+-- >         Streams.connect (responseBody resp)
+--
+-- For non-streaming request bodies, study the 'RequestBody' type,
+-- which also
+-- accepts strict \/ lazy bytestrings
+
+module System.IO.Streams.HTTP (
+    -- * http-client
+    -- $httpclient
+    module Network.HTTP.Client
+  , module Network.HTTP.Client.TLS
+    -- * io-streams Interface
+  , withHTTP
+  , streamN
+  , stream
+  ) where
+
+import           Control.Applicative     ( (<$>) )
+import           Control.Monad.IO.Class  ( liftIO )
+import           Data.ByteString         ( ByteString )
+import qualified Data.ByteString as B
+import           Data.Int                ( Int64 )
+import           Network.HTTP.Client
+import           Network.HTTP.Client.TLS
+
+import           System.IO               ( stdout )
+import           System.IO.Streams       ( InputStream
+                                         , OutputStream
+                                         , Generator
+                                         )
+
+import qualified System.IO.Streams as Streams
+import           System.IO.Streams.ByteString
+
+{- $httpclient
+    This module is a thin @io-streams@ wrapper around the @http-client@ and
+    @http-client-tls@ libraries.
+
+    Read the documentation in the "Network.HTTP.Client" module of the
+    @http-client@ library to learn about how to:
+
+    * manage connections using connection pooling,
+
+    * use more advanced request\/response features,
+
+    * handle exceptions, and:
+
+    * manage cookies.
+
+    @http-client-tls@ provides support for TLS connections (i.e.
+     HTTPS).
+-}
+
+------------------------------------------------------------------------------
+-- | Send an HTTP 'Request' and wait for an HTTP 'Response'
+withHTTP
+    :: Request
+    -> Manager
+    -> (Response (InputStream ByteString) -> IO a)
+    -> IO a
+withHTTP r m k = withResponse r m k'
+  where
+    k' resp = do
+      p <- (from . brRead . responseBody) resp
+      k (resp { responseBody = p})
+{-# INLINABLE withHTTP #-}
+
+------------------------------------------------------------------------------
+-- | Produce an InputStream from a streaming IO ByteString action
+from :: IO ByteString -> IO (InputStream ByteString)
+from io = Streams.makeInputStream $ do
+            bs <- io
+            return $ if B.null bs
+              then Nothing
+              else Just bs
+
+------------------------------------------------------------------------------
+-- | Stream body of request
+to :: InputStream ByteString -> (IO ByteString -> IO ()) -> IO ()
+to is f = f $ maybe B.empty id <$> Streams.read is
+
+------------------------------------------------------------------------------
+-- | Stream body of request
+stream :: InputStream ByteString -> RequestBody
+stream p = RequestBodyStreamChunked (to p)
+{-# INLINABLE stream #-}
+
+------------------------------------------------------------------------------
+-- | Stream with N bytes exactly
+streamN :: Int64 -> InputStream ByteString -> RequestBody
+streamN n p = RequestBodyStream n (to p)
+{-# INLINABLE streamN #-}
+
