diff --git a/network-messagepack-rpc.cabal b/network-messagepack-rpc.cabal
--- a/network-messagepack-rpc.cabal
+++ b/network-messagepack-rpc.cabal
@@ -1,5 +1,5 @@
 name:                network-messagepack-rpc
-version:             0.1.1.4
+version:             0.1.2.0
 synopsis:            MessagePack RPC
 description:         [MessagePack RPC](https://github.com/msgpack-rpc/msgpack-rpc/blob/master/spec.md) library based on the "data-msgpack" package.
 homepage:            https://github.com/iij-ii/direct-hs/tree/master/network-messagepack-rpc
@@ -16,6 +16,7 @@
   ghc-options: -Wall
   exposed-modules: Data.MessagePack.RPC
                  , Network.MessagePack.RPC.Client
+                 , Network.MessagePack.RPC.Client.Internal
   build-depends:
       base >= 4.7 && < 5
     , bytestring
diff --git a/src/Network/MessagePack/RPC/Client.hs b/src/Network/MessagePack/RPC/Client.hs
--- a/src/Network/MessagePack/RPC/Client.hs
+++ b/src/Network/MessagePack/RPC/Client.hs
@@ -1,3 +1,4 @@
+{-# LANGUAGE CPP               #-}
 {-# LANGUAGE OverloadedStrings #-}
 
 -- | Backend-free MessagePack RPC Client.
@@ -23,55 +24,31 @@
     )
 where
 
-import           Control.Concurrent      (ThreadId, forkFinally, forkIO,
-                                          killThread)
-import           Control.Concurrent.MVar (MVar)
-import qualified Control.Concurrent.MVar as MVar
-import qualified Control.Exception.Safe  as E
-import           Control.Monad           (forever, void, when)
-import qualified Data.ByteString         as B
-import qualified Data.ByteString.Lazy    as BL
-import qualified Data.HashMap.Strict     as HM
-import           Data.IORef              (IORef)
-import qualified Data.IORef              as IORef
-import qualified Data.MessagePack        as MsgPack
-import           Data.Monoid             ((<>))
-import           System.IO               (hPrint, stderr)
-import           System.Timeout          (timeout)
+import           Control.Concurrent                      (forkFinally, forkIO,
+                                                          killThread)
+import qualified Control.Concurrent.MVar                 as MVar
+import qualified Control.Exception.Safe                  as E
+import           Control.Monad                           (forever, void, when)
+import qualified Data.ByteString.Lazy                    as BL
+import qualified Data.HashMap.Strict                     as HM
+import qualified Data.IORef                              as IORef
+import qualified Data.MessagePack                        as MsgPack
+#if !MIN_VERSION_base(4,13,0)
+import           Data.Monoid                             ((<>))
+#endif
+import           System.IO                               (hPrint, stderr)
+import           System.Timeout                          (timeout)
 
 import           Data.MessagePack.RPC
-
--- | A client data type for MessagePack RPC.
-data Client = Client {
-    clientSessionState :: !SessionState
-  , clientBackend      :: !Backend
-  , clientLog          :: Logger
-  , clientFormat       :: Formatter
-  , clientHandlerTid   :: IORef (Maybe ThreadId)
-  }
-
-data SessionState = SessionState {
-    lastMessageId :: IORef MessageId
-  , dispatchTable :: IORef (HM.HashMap MessageId (MVar Result))
-  }
-
--- | Result type of a RPC call.
---   Described as "error" and "result" of "Response Message"
---   in [the spec of MessagePack RPC](https://github.com/msgpack-rpc/msgpack-rpc/blob/master/spec.md#response-message).
-type Result = Either MsgPack.Object MsgPack.Object
+import           Network.MessagePack.RPC.Client.Internal
 
 -- | Notification handler. The 3rd argument is response objects.
 type NotificationHandler = Client -> MethodName -> [MsgPack.Object] -> IO ()
 
 -- | Notification handler. The 2nd argument is message id to be used
 --   for replying. The 3rd argument is response objects.
-type RequestHandler = Client -> MessageId -> MethodName -> [MsgPack.Object] -> IO ()
-
--- | Logger type. Should print out the message passed as a first argument somewhere.
-type Logger = String -> IO ()
-
--- | Convert 'Message' into a @String@ to print out by 'Logger'
-type Formatter = Message -> String
+type RequestHandler
+    = Client -> MessageId -> MethodName -> [MsgPack.Object] -> IO ()
 
 -- | Configuration for MessagePack RPC.
 data Config = Config {
@@ -95,19 +72,11 @@
     { notificationHandler = \_ _ _ -> return ()
     , requestHandler      = \_ _ _ _ -> return ()
     , logger              = \_ -> return ()
-    , exceptionHandlers   = [E.Handler $ \(E.SomeException e) -> hPrint stderr e]
+    , exceptionHandlers = [E.Handler $ \(E.SomeException e) -> hPrint stderr e]
     , formatter           = show
     , waitRequestHandler  = False
     }
 
--- | Backend IO functions.
---   Any receiving / sending actions are performed by calling these functions.
-data Backend = Backend {
-    backendSend  :: B.ByteString -> IO () -- ^ Sending
-  , backendRecv  :: IO B.ByteString -- ^ Receiving
-  , backendClose :: IO () -- ^ Closing
-  }
-
 -- TODO: Returns any exception
 -- | Calling RPC.
 call :: Client -> MethodName -> [MsgPack.Object] -> IO Result
@@ -173,10 +142,6 @@
                                                params
     where ss = clientSessionState client
 
-initSessionState :: IO SessionState
-initSessionState =
-    SessionState <$> IORef.newIORef 0 <*> IORef.newIORef HM.empty
-
 -- | Executing the action in the 3rd argument with a 'Client'.
 withClient :: Config -> Backend -> (Client -> IO a) -> IO a
 withClient config backend action = do
@@ -187,8 +152,7 @@
     tid <- forkFinally (receiverThread client config)
         $ \_ -> MVar.putMVar wait ()
     IORef.writeIORef tidref $ Just tid
-    takeAction client wait
-        `E.finally` (backendClose backend >> killThread tid)
+    takeAction client wait `E.finally` (backendClose backend >> killThread tid)
   where
     takeAction client wait = do
         returned <- action client
diff --git a/src/Network/MessagePack/RPC/Client/Internal.hs b/src/Network/MessagePack/RPC/Client/Internal.hs
new file mode 100644
--- /dev/null
+++ b/src/Network/MessagePack/RPC/Client/Internal.hs
@@ -0,0 +1,49 @@
+module Network.MessagePack.RPC.Client.Internal where
+
+import           Control.Concurrent      (ThreadId)
+import           Control.Concurrent.MVar (MVar)
+import qualified Data.ByteString         as B
+import           Data.HashMap.Strict     (HashMap)
+import qualified Data.HashMap.Strict     as HM
+import           Data.IORef              (IORef)
+import qualified Data.IORef              as IORef
+import qualified Data.MessagePack        as MsgPack
+
+import           Data.MessagePack.RPC
+
+-- | A client data type for MessagePack RPC.
+data Client = Client {
+    clientSessionState :: !SessionState
+  , clientBackend      :: !Backend
+  , clientLog          :: Logger
+  , clientFormat       :: Formatter
+  , clientHandlerTid   :: IORef (Maybe ThreadId)
+  }
+
+data SessionState = SessionState {
+    lastMessageId :: IORef MessageId
+  , dispatchTable :: IORef (HashMap MessageId (MVar Result))
+  }
+
+-- | Backend IO functions.
+--   Any receiving / sending actions are performed by calling these functions.
+data Backend = Backend {
+    backendSend  :: B.ByteString -> IO () -- ^ Sending
+  , backendRecv  :: IO B.ByteString -- ^ Receiving
+  , backendClose :: IO () -- ^ Closing
+  }
+
+-- | Logger type. Should print out the message passed as a first argument somewhere.
+type Logger = String -> IO ()
+
+-- | Convert 'Message' into a @String@ to print out by 'Logger'
+type Formatter = Message -> String
+
+-- | Result type of a RPC call.
+--   Described as "error" and "result" of "Response Message"
+--   in [the spec of MessagePack RPC](https://github.com/msgpack-rpc/msgpack-rpc/blob/master/spec.md#response-message).
+type Result = Either MsgPack.Object MsgPack.Object
+
+initSessionState :: IO SessionState
+initSessionState =
+    SessionState <$> IORef.newIORef 0 <*> IORef.newIORef HM.empty
