diff --git a/ChangeLog.md b/ChangeLog.md
new file mode 100644
--- /dev/null
+++ b/ChangeLog.md
@@ -0,0 +1,5 @@
+# Revision history for http-pony-transformer-http
+
+## 0.1.0.0  -- YYYY-mm-dd
+
+* First version. Released on an unsuspecting world.
diff --git a/LICENSE b/LICENSE
new file mode 100644
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,30 @@
+Copyright (c) 2016, Jinjing Wang
+
+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 Jinjing Wang 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.hs b/Setup.hs
new file mode 100644
--- /dev/null
+++ b/Setup.hs
@@ -0,0 +1,2 @@
+import Distribution.Simple
+main = defaultMain
diff --git a/http-pony-transformer-http.cabal b/http-pony-transformer-http.cabal
new file mode 100644
--- /dev/null
+++ b/http-pony-transformer-http.cabal
@@ -0,0 +1,27 @@
+-- Initial http-pony-transformer-http.cabal generated by cabal init.  For 
+-- further documentation, see http://haskell.org/cabal/users-guide/
+
+name:                http-pony-transformer-http
+version:             0.1.0.0
+-- synopsis:            
+description:         Transform to a basic HTTP interface
+license:             BSD3
+license-file:        LICENSE
+author:              Jinjing Wang
+maintainer:          nfjinjing@gmail.com
+-- copyright:           
+category:            Network
+build-type:          Simple
+extra-source-files:  ChangeLog.md
+cabal-version:       >=1.10
+
+library
+  exposed-modules:     Network.HTTP.Pony.Transformer.HTTP
+                     , Network.HTTP.Pony.Transformer.HTTP.Parser
+                     , Network.HTTP.Pony.Transformer.HTTP.Type
+                     , Network.HTTP.Pony.Transformer.HTTP.Builder
+  -- other-modules:       
+  -- other-extensions:    OverloadedStrings
+  build-depends:       base >=4.9 && <4.10, bytestring >=0.10, pipes >=4.1, transformers >=0.5, attoparsec >=0.13, pipes-attoparsec >=0.5
+  hs-source-dirs:      src
+  default-language:    Haskell2010
diff --git a/src/Network/HTTP/Pony/Transformer/HTTP.hs b/src/Network/HTTP/Pony/Transformer/HTTP.hs
new file mode 100644
--- /dev/null
+++ b/src/Network/HTTP/Pony/Transformer/HTTP.hs
@@ -0,0 +1,30 @@
+-- | The raw HTTP transformer
+
+module Network.HTTP.Pony.Transformer.HTTP where
+
+import           Data.ByteString.Char8 (ByteString)
+import           Pipes (Producer, Consumer, runEffect, (>->))
+
+import qualified Network.HTTP.Pony.Transformer.HTTP.Builder as Builder
+import qualified Network.HTTP.Pony.Transformer.HTTP.Parser as Parser
+import           Network.HTTP.Pony.Transformer.HTTP.Type (Middleware, Request', Response')
+
+http :: (Monad m) => Middleware m
+                                (Producer ByteString m a)
+                                (Producer ByteString m ())
+                                (Request' ByteString m a)
+                                (Response' ByteString m b)
+http app pull = do
+  maybeRequest <- Parser.parseMessage pull (pure ())
+
+  case maybeRequest of
+    Just (Right request) -> do
+      response <- app request
+
+      pure (Builder.message response >> pure ())
+
+    _ -> (pure . pure) ()
+
+    -- Just (Left err) -> pure - pure - err
+    -- _ -> pure Nothing
+
diff --git a/src/Network/HTTP/Pony/Transformer/HTTP/Builder.hs b/src/Network/HTTP/Pony/Transformer/HTTP/Builder.hs
new file mode 100644
--- /dev/null
+++ b/src/Network/HTTP/Pony/Transformer/HTTP/Builder.hs
@@ -0,0 +1,28 @@
+-- | Builder
+
+{-# LANGUAGE OverloadedStrings #-}
+
+module Network.HTTP.Pony.Transformer.HTTP.Builder where
+
+import Data.ByteString (ByteString)
+import Pipes (yield, (~>), each, Producer)
+
+import Network.HTTP.Pony.Transformer.HTTP.Type (Header, Request')
+
+header :: Monad m => Header -> Producer ByteString m ()
+header (key, value) = do
+  yield key
+  yield ": "
+  yield value
+  yield "\n"
+
+
+message :: Monad m => Request' ByteString m r -> Producer ByteString m r
+message ((startLine, headers), body) = do
+  yield startLine
+  yield "\n"
+
+  (each ~> header) headers
+
+  yield "\n"
+  body
diff --git a/src/Network/HTTP/Pony/Transformer/HTTP/Parser.hs b/src/Network/HTTP/Pony/Transformer/HTTP/Parser.hs
new file mode 100644
--- /dev/null
+++ b/src/Network/HTTP/Pony/Transformer/HTTP/Parser.hs
@@ -0,0 +1,56 @@
+-- | 
+
+module Network.HTTP.Pony.Transformer.HTTP.Parser where
+
+import           Control.Applicative ((<|>))
+import           Control.Monad.Trans.State.Strict (runStateT)
+import           Data.Attoparsec.ByteString
+import qualified Data.Attoparsec.ByteString.Char8 as Char
+import           Data.ByteString.Char8 (ByteString)
+import qualified Data.ByteString.Char8 as B
+import           Pipes (Producer)
+import           Pipes.Attoparsec (ParsingError(..))
+import qualified Pipes.Attoparsec as PA
+
+import           Network.HTTP.Pony.Transformer.HTTP.Type
+
+-- https://www.w3.org/Protocols/rfc2616/rfc2616-sec4.html#sec4.2
+
+
+startLine :: Parser ByteString
+startLine = takeTill Char.isEndOfLine <* Char.endOfLine
+
+requestLine :: Parser ByteString
+requestLine = startLine
+
+statusLine :: Parser ByteString
+statusLine = startLine
+
+headers :: Parser [Header]
+headers = do
+  many' header <* Char.endOfLine
+
+token :: Parser ByteString
+token = fmap B.pack (many1' (Char.letter_ascii <|> Char.char '-'))
+
+header :: Parser Header
+header = do
+  fieldName <- token
+  Char.char ':'
+  Char.skipSpace
+  fieldValue <- takeTill Char.isEndOfLine
+  Char.endOfLine
+  pure (fieldName, fieldValue)
+
+message :: Parser (ByteString, [Header])
+message = do
+  Char.skipSpace
+  (,) <$> startLine <*> headers
+
+parseMessage :: (Monad m) => Producer ByteString m r
+                          -> m a
+                          -> m (Maybe (Either ParsingError (Message' ByteString m r)))
+parseMessage p errHandler = do
+  (r, body) <- runStateT (PA.parse message) p
+
+  pure (fmap (fmap (\(x, xs) -> ((x, xs), body))) r)
diff --git a/src/Network/HTTP/Pony/Transformer/HTTP/Type.hs b/src/Network/HTTP/Pony/Transformer/HTTP/Type.hs
new file mode 100644
--- /dev/null
+++ b/src/Network/HTTP/Pony/Transformer/HTTP/Type.hs
@@ -0,0 +1,19 @@
+module Network.HTTP.Pony.Transformer.HTTP.Type where
+
+import Data.ByteString.Char8 (ByteString)
+import Pipes (Producer, Consumer, runEffect, (>->))
+
+type StartLine = ByteString
+type Header = (ByteString, ByteString)
+
+type HttpType = (StartLine, [Header])
+
+type Message t a m r = (t, Producer a m r)
+type Message' a m r = (HttpType, Producer a m r)
+
+type Request t a m r = Message t a m r
+type Request' a m r = Message' a m r
+type Response t a m r = Message t a m r
+type Response' a m r = Message' a m r
+
+type Middleware f s t a b = (a -> f b) -> s -> f t
