diff --git a/Example/Echo.hs b/Example/Echo.hs
new file mode 100644
--- /dev/null
+++ b/Example/Echo.hs
@@ -0,0 +1,77 @@
+{-# LANGUAGE Rank2Types #-}
+--------------------------------------------------------------------------------
+-- |
+-- Module      : Example.Echo
+-- Copyright   : (c) Moritz Angermann 2014
+-- License     : MIT
+--
+-- Maintainer  : moritz@lichtzwerge.de
+-- Stability   : stable
+-- Portability : portable
+--
+-- An echo service on port 2000
+--
+-- To start the server run
+-- > $ echo server
+--
+-- You can then run the client
+-- > $ echo client
+--
+-- Or connect to the server with telnet
+-- > $ telnet localhost 2000
+--
+--------------------------------------------------------------------------------
+module Main (main) where
+import           Network.Simple.TCP
+import           Data.ByteString.Char8   ( pack, unpack )
+import           System.Environment      ( getProgName, getArgs )
+import           Control.Monad           ( unless )
+
+import Network.Service
+import Network.Transport.Encoding.Base64 (mkService)
+
+-- | Make a service server running on the executing host.
+mkServiceServer :: ServiceMessage a
+                   => ServiceName      -- ^ the port
+                   -> ServiceHandler a -- ^ a handler to handle connections.
+                   -> IO ()
+mkServiceServer port shandler = serve HostAny port handler
+  where handler :: (Socket, SockAddr) -> IO ()
+        handler x = mkService x >>= shandler
+
+-- | Make a service client
+mkServiceClient :: ServiceMessage a
+                   => HostName       -- ^ The hostname that provides a 'Service a'.
+                   -> ServiceName    -- ^ The port the service runs at.
+                   -> IO (Service a) -- ^ The client. (Service interface)
+mkServiceClient h p = connect h p mkService
+
+-- | We use a simple data type for communication.
+--   All it holds is a simple string.
+data Message = Msg String
+
+-- | Turning a String message into a bytestring.
+--   Trivially through pack and unpack.
+instance ServiceMessage Message where
+  toBS (Msg s) = pack s
+  fromBS = Msg . unpack
+
+main :: IO ()
+main = do
+  args <- getArgs
+  prog <- getProgName
+  
+  case args of
+    ["server"] -> mkServiceServer "2000" handler
+    ["client"] -> do
+      service <- mkServiceClient "localhost" "2000"
+      let msg = "Hello World!"
+      putStrLn $ "[Client] Sending: " ++ msg
+      sSend service $ Msg msg
+      Msg resp <- sRecv service
+      putStrLn $ "[Client] Received: " ++ resp
+      sTerm service
+    _          -> putStrLn $ "Usage: " ++ prog ++ " (server|client)"
+
+  where handler :: ServiceHandler Message
+        handler service = sRecv service >>= sSend service >> sDone service >>= flip unless (handler service)
diff --git a/LICENSE b/LICENSE
new file mode 100644
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,20 @@
+Copyright (c) 2014 Moritz Angermann
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be included
+in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
diff --git a/Network/Service.hs b/Network/Service.hs
new file mode 100644
--- /dev/null
+++ b/Network/Service.hs
@@ -0,0 +1,42 @@
+{-# LANGUAGE Rank2Types #-}
+--------------------------------------------------------------------------------
+-- |
+-- Module      : Network.Service
+-- Copyright   : (c) Moritz Angermann 2014
+-- License     : MIT
+--
+-- Maintainer  : moritz@lichtzwerge.de
+-- Stability   : stable
+-- Portability : portable
+--
+-- A service is an endpoint that can receive and send messages.
+--
+--------------------------------------------------------------------------------
+module Network.Service where
+
+import Data.ByteString (ByteString)
+
+-- | Services operate on Messages, the ServiceMessage class abstracts
+--   the serialization.
+class ServiceMessage a where
+  toBS :: a -> ByteString   -- ^ serialization to ByteString representation
+  fromBS :: ByteString -> a -- ^ deserialization from ByteString representation
+
+-- | A Service of a certain Message data.
+data Service a = Service
+                 { sDone :: IO Bool    -- ^ tells whether the service is done or not.
+                 , sRecv :: IO a       -- ^ receive a message.
+                 , sSend :: a -> IO () -- ^ send a message.
+                 , sTerm :: IO ()      -- ^ terminate the service.
+                 }
+-- | A handler takes a service and returns an IO action.
+--   The idea is that a service handler will 'run' a service
+--
+-- a simple echo handler might look like the following:
+--
+-- > handler service = do { msg <- sRecv service
+-- >                      ; sSend service msg
+-- >                      ; isDone <- sDone service
+-- >                      ; unless isDone (handler service)
+-- >                      }
+type ServiceHandler a = Service a -> IO ()
diff --git a/Network/Transport/Encoding/Base64.hs b/Network/Transport/Encoding/Base64.hs
new file mode 100644
--- /dev/null
+++ b/Network/Transport/Encoding/Base64.hs
@@ -0,0 +1,46 @@
+--------------------------------------------------------------------------------
+-- |
+-- Module      : Network.Transport.Encoding.Base64
+-- Copyright   : (c) Moritz Angermann 2014
+-- License     : MIT
+--
+-- Maintainer  : moritz@lichtzwerge.de
+-- Stability   : stable
+-- Portability : portable
+--
+-- A trivial service that uses base64 as encoding for the
+-- messages and newlines for message separation.
+--------------------------------------------------------------------------------
+module Network.Transport.Encoding.Base64 (mkService) where
+import           Network.Socket          (Socket, SockAddr, socketToHandle)
+import           System.IO               (hSetBuffering, hGetContents, hPutStrLn, hClose
+                                         ,IOMode( ReadWriteMode ), BufferMode( LineBuffering ))
+import           Control.Concurrent      (newMVar, modifyMVar)
+import           Data.ByteString.Base64  (encode, decode)
+import           Data.ByteString.Char8   (pack, unpack)
+import           Data.ByteString         (ByteString)
+
+import           Network.Service
+
+-- hack.
+decode' :: ByteString -> ByteString
+decode' bs = let Right res = decode bs in res
+
+-- | Builds a simple service, that uses base64 as the base
+--   encoding for the messages.  Messages are separated by
+--   newlines.
+mkService :: ServiceMessage a
+             => (Socket, SockAddr) -- ^ The socket and socket address to the service is bound on.
+             -> IO (Service a)     -- ^ The service to be used.
+mkService (sock, addr) = do
+  hdl <- socketToHandle sock ReadWriteMode
+  hSetBuffering hdl LineBuffering
+  messages <- lines `fmap` (hGetContents hdl)
+  messageMVar <- newMVar messages
+  return $ Service { sDone = modifyMVar messageMVar
+                             (\ms -> return (ms, ms == []))
+                   , sRecv = modifyMVar messageMVar
+                             (\ms -> return (tail ms, fromBS . decode' . pack $ head ms))
+                   , sSend = hPutStrLn hdl . unpack . encode . toBS
+                   , sTerm = hClose hdl
+                   }
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/network-service.cabal b/network-service.cabal
new file mode 100644
--- /dev/null
+++ b/network-service.cabal
@@ -0,0 +1,61 @@
+-- Initial network-service.cabal generated by cabal init.  For further 
+-- documentation, see http://haskell.org/cabal/users-guide/
+
+name:                network-service
+version:             0.1.0.0
+synopsis:            Provide a service at the data type level.
+description:         Thin very layer over network-simple, that allows to write
+                     a service that can be communicated with at the data level.
+                     Makes it trivial to build a services upon a data type,
+                     provided a ByteString serialization can be given.
+homepage:            https://github.com/angerman/network-service
+license:             MIT
+license-file:        LICENSE
+author:              Moritz Angermann
+maintainer:          moritz@lichtzwerge.de
+copyright:           2014 Moritz Angermann
+category:            Network
+build-type:          Simple
+-- extra-source-files:  
+cabal-version:       >=1.10
+
+flag example
+  description: Build example executables to showcase the library
+  default: False
+
+flag documentation
+  default: False
+
+source-repository head
+  type:     git
+  location: https://github.com/angerman/network-service.git
+
+library
+  if flag(documentation)
+     build-depends:    hscolour
+  exposed-modules:     Network.Service, Network.Transport.Encoding.Base64
+  -- other-modules:       
+  other-extensions:    Rank2Types
+  build-depends:       base >=4.7 && <4.8
+                     , network >=2.6 && <2.7
+                     , bytestring >=0.10 && <0.11
+                     , base64-bytestring >=1.0 && <1.1
+  -- hs-source-dirs:      
+  default-language:    Haskell2010
+
+executable echo
+  if flag(example)
+     Buildable: True
+  else
+     Buildable: False
+     
+  main-is:             Example/Echo.hs
+  other-modules:       Network.Service, Network.Transport.Encoding.Base64
+  -- other-extensions:
+  build-depends:       base >=4.7 && <4.8
+                     , network >=2.6 && <2.7
+                     , network-simple >= 0.4 && <0.5
+                     , bytestring >=0.10 && <0.11
+                     , base64-bytestring >=1.0 && <1.1
+  -- hs-source-dirs:
+  default-language:    Haskell2010
