diff --git a/.travis.yml b/.travis.yml
--- a/.travis.yml
+++ b/.travis.yml
@@ -35,9 +35,12 @@
     - compiler: "ghc-8.0.2"
     # env: TEST=--disable-tests BENCH=--disable-benchmarks
       addons: {apt: {packages: [ghc-ppa-tools,cabal-install-head,ghc-8.0.2], sources: [hvr-ghc]}}
-    - compiler: "ghc-8.2.1"
+    - compiler: "ghc-8.2.2"
     # env: TEST=--disable-tests BENCH=--disable-benchmarks
-      addons: {apt: {packages: [ghc-ppa-tools,cabal-install-head,ghc-8.2.1], sources: [hvr-ghc]}}
+      addons: {apt: {packages: [ghc-ppa-tools,cabal-install-head,ghc-8.2.2], sources: [hvr-ghc]}}
+    - compiler: "ghc-8.4.3"
+    # env: TEST=--disable-tests BENCH=--disable-benchmarks
+      addons: {apt: {packages: [ghc-ppa-tools,cabal-install-head,ghc-8.4.3], sources: [hvr-ghc]}}
 
 before_install:
  - HC=${CC}
diff --git a/ChangeLog.md b/ChangeLog.md
--- a/ChangeLog.md
+++ b/ChangeLog.md
@@ -1,3 +1,8 @@
+## 0.3.0
+
+* Upgrade http-conduit dependencies to:
+  http-conduit >= 2.0 && < 2.4 [#59](https://github.com/himura/twitter-conduit/pull/59)
+
 ## 0.2.2
 
 * Upgrade http-conduit and http-client dependencies to:
diff --git a/Web/Twitter/Conduit/Base.hs b/Web/Twitter/Conduit/Base.hs
--- a/Web/Twitter/Conduit/Base.hs
+++ b/Web/Twitter/Conduit/Base.hs
@@ -32,6 +32,7 @@
 import Control.Lens
 import Control.Monad.Base
 import Control.Monad.Catch (MonadThrow (..))
+import Control.Monad.IO.Class
 import Control.Monad.Trans.Resource (MonadResource, ResourceT, runResourceT)
 import Data.Aeson
 import Data.Aeson.Lens
@@ -82,7 +83,11 @@
             => TWInfo
             -> HTTP.Manager
             -> HTTP.Request
+#if MIN_VERSION_http_conduit(2,3,0)
+            -> m (Response (C.ConduitM () ByteString m ()))
+#else
             -> m (Response (C.ResumableSource m ByteString))
+#endif
 getResponse TWInfo{..} mgr req = do
     signedReq <- signOAuth (twOAuth twToken) (twCredential twToken) $ req { HTTP.proxy = twProxy }
     res <- HTTP.http signedReq mgr
@@ -95,10 +100,20 @@
 endpoint :: String
 endpoint = "https://api.twitter.com/1.1/"
 
-getValue :: Response (C.ResumableSource (ResourceT IO) ByteString)
+getValue ::
+#if MIN_VERSION_http_conduit(2,3,0)
+            Response (C.ConduitM () ByteString (ResourceT IO) ())
+#else
+            Response (C.ResumableSource (ResourceT IO) ByteString)
+#endif
          -> ResourceT IO (Response Value)
 getValue res = do
-    value <- responseBody res C.$$+- sinkJSON
+    value <-
+#if MIN_VERSION_http_conduit(2,3,0)
+      C.runConduit $ responseBody res C..| sinkJSON
+#else
+      responseBody res C.$$+- sinkJSON
+#endif
     return $ res { responseBody = value }
 
 checkResponse :: Response Value
@@ -119,7 +134,11 @@
     sci = HT.statusCode responseStatus
 
 getValueOrThrow :: FromJSON a
+#if MIN_VERSION_http_conduit(2,3,0)
+                => Response (C.ConduitM () ByteString (ResourceT IO) ())
+#else
                 => Response (C.ResumableSource (ResourceT IO) ByteString)
+#endif
                 -> ResourceT IO (Response a)
 getValueOrThrow res = do
     res' <- getValue res
@@ -195,13 +214,13 @@
                   -> IO (Response value)
 callWithResponse' info mgr req =
     runResourceT $ do
-        res <- getResponse info mgr =<< liftBase (makeRequest req)
+        res <- getResponse info mgr =<< liftIO (makeRequest req)
         getValueOrThrow res
 
 -- | A wrapper function to perform multiple API request with changing @max_id@ parameter.
 --
 -- This function cooperate with instances of 'HasMaxIdParam'.
-sourceWithMaxId :: ( MonadBase IO m
+sourceWithMaxId :: ( MonadIO m
                    , FromJSON responseType
                    , AsStatus responseType
                    , HasMaxIdParam (APIRequest apiName [responseType])
@@ -213,7 +232,7 @@
 sourceWithMaxId info mgr = loop
   where
     loop req = do
-        res <- liftBase $ call info mgr req
+        res <- liftIO $ call info mgr req
         case getMinId res of
             Just mid -> do
                 CL.sourceList res
@@ -226,8 +245,8 @@
 -- so you can choose an arbitrarily type of FromJSON instances.
 --
 -- This function cooperate with instances of 'HasMaxIdParam'.
-sourceWithMaxId' :: ( MonadBase IO m
-                    ,  HasMaxIdParam (APIRequest apiName [responseType])
+sourceWithMaxId' :: ( MonadIO m
+                    , HasMaxIdParam (APIRequest apiName [responseType])
                     )
                  => TWInfo -- ^ Twitter Setting
                  -> HTTP.Manager
@@ -236,7 +255,7 @@
 sourceWithMaxId' info mgr = loop
   where
     loop req = do
-        res <- liftBase $ call' info mgr req
+        res <- liftIO $ call' info mgr req
         case getMinId res of
             Just mid -> do
                 CL.sourceList res
@@ -247,7 +266,7 @@
 -- | A wrapper function to perform multiple API request with changing @cursor@ parameter.
 --
 -- This function cooperate with instances of 'HasCursorParam'.
-sourceWithCursor :: ( MonadBase IO m
+sourceWithCursor :: ( MonadIO m
                     , FromJSON responseType
                     , CursorKey ck
                     , HasCursorParam (APIRequest apiName (WithCursor ck responseType))
@@ -260,7 +279,7 @@
   where
     loop 0 = CL.sourceNull
     loop cur = do
-        res <- liftBase $ call info mgr $ req & cursor ?~ cur
+        res <- liftIO $ call info mgr $ req & cursor ?~ cur
         CL.sourceList $ contents res
         loop $ nextCursor res
 
@@ -269,7 +288,7 @@
 -- so you can choose an arbitrarily type of FromJSON instances.
 --
 -- This function cooperate with instances of 'HasCursorParam'.
-sourceWithCursor' :: ( MonadBase IO m
+sourceWithCursor' :: ( MonadIO m
                      , CursorKey ck
                      , HasCursorParam (APIRequest apiName (WithCursor ck responseType))
                      )
@@ -284,12 +303,12 @@
     relax = unsafeCoerce
     loop 0 = CL.sourceNull
     loop cur = do
-        res <- liftBase $ call info mgr $ relax $ req & cursor ?~ cur
+        res <- liftIO $ call info mgr $ relax $ req & cursor ?~ cur
         CL.sourceList $ contents res
         loop $ nextCursor res
 
 -- | A wrapper function to perform multiple API request with @SearchResult@.
-sourceWithSearchResult :: ( MonadBase IO m
+sourceWithSearchResult :: ( MonadIO m
                           , FromJSON responseType
                           )
                        => TWInfo -- ^ Twitter Setting
@@ -297,7 +316,7 @@
                        -> APIRequest apiName (SearchResult [responseType])
                        -> m (SearchResult (C.Source m responseType))
 sourceWithSearchResult info mgr req = do
-    res <- liftBase $ call info mgr req
+    res <- liftIO $ call info mgr req
     let body = CL.sourceList (res ^. searchResultStatuses) <>
                loop (res ^. searchResultSearchMetadata . searchMetadataNextResults)
     return $ res & searchResultStatuses .~ body
@@ -307,19 +326,19 @@
     loop (Just nextResultsStr) = do
         let nextResults = nextResultsStr & HT.parseSimpleQuery . T.encodeUtf8 & traversed . _2 %~ (PVString . T.decodeUtf8)
             nextParams = M.toList $ M.union (M.fromList nextResults) origQueryMap
-        res <- liftBase $ call info mgr $ req & params .~ nextParams
+        res <- liftIO $ call info mgr $ req & params .~ nextParams
         CL.sourceList (res ^. searchResultStatuses)
         loop $ res ^. searchResultSearchMetadata . searchMetadataNextResults
 
 -- | A wrapper function to perform multiple API request with @SearchResult@.
-sourceWithSearchResult' :: ( MonadBase IO m
+sourceWithSearchResult' :: ( MonadIO m
                            )
                         => TWInfo -- ^ Twitter Setting
                         -> HTTP.Manager
                         -> APIRequest apiName (SearchResult [responseType])
                         -> m (SearchResult (C.Source m Value))
 sourceWithSearchResult' info mgr req = do
-    res <- liftBase $ call info mgr $ relax req
+    res <- liftIO $ call info mgr $ relax req
     let body = CL.sourceList (res ^. searchResultStatuses) <>
                loop (res ^. searchResultSearchMetadata . searchMetadataNextResults)
     return $ res & searchResultStatuses .~ body
@@ -332,7 +351,7 @@
     loop (Just nextResultsStr) = do
         let nextResults = nextResultsStr & HT.parseSimpleQuery . T.encodeUtf8 & traversed . _2 %~ (PVString . T.decodeUtf8)
             nextParams = M.toList $ M.union (M.fromList nextResults) origQueryMap
-        res <- liftBase $ call info mgr $ relax $ req & params .~ nextParams
+        res <- liftIO $ call info mgr $ relax $ req & params .~ nextParams
         CL.sourceList (res ^. searchResultStatuses)
         loop $ res ^. searchResultSearchMetadata . searchMetadataNextResults
 
diff --git a/Web/Twitter/Conduit/Stream.hs b/Web/Twitter/Conduit/Stream.hs
--- a/Web/Twitter/Conduit/Stream.hs
+++ b/Web/Twitter/Conduit/Stream.hs
@@ -32,6 +32,7 @@
 import Web.Twitter.Conduit.Request
 import Web.Twitter.Conduit.Response
 
+import Control.Monad.Catch
 import Control.Monad.IO.Class
 import Control.Monad.Trans.Resource (MonadResource)
 import Data.Aeson
@@ -44,6 +45,8 @@
 import qualified Data.Text as T
 import qualified Network.HTTP.Conduit as HTTP
 
+#if MIN_VERSION_conduit(1,3,0)
+#else
 #if MIN_VERSION_conduit(1,0,16)
 ($=+) :: MonadIO m
       => CI.ResumableSource m a
@@ -55,22 +58,47 @@
     (src, finalizer) <- C.unwrapResumable rsrc
     return $ CI.ResumableSource (src C.$= cndt) finalizer
 #endif
+#endif
 
-stream :: (MonadResource m, FromJSON responseType)
+stream ::
+          ( MonadResource m
+          , FromJSON responseType
+#if MIN_VERSION_conduit(1,3,0)
+          , MonadThrow m
+#endif
+          )
        => TWInfo
        -> HTTP.Manager
        -> APIRequest apiName responseType
+#if MIN_VERSION_http_conduit(2,3,0)
+        -> m (C.ConduitM () responseType m ())
+#else
        -> m (C.ResumableSource m responseType)
+#endif
 stream = stream'
 
-stream' :: (MonadResource m, FromJSON value)
+stream' ::
+           ( MonadResource m
+           , FromJSON value
+#if MIN_VERSION_conduit(1,3,0)
+           , MonadThrow m
+#endif
+           )
         => TWInfo
         -> HTTP.Manager
         -> APIRequest apiName responseType
+#if MIN_VERSION_http_conduit(2,3,0)
+        -> m (C.ConduitM () value m ())
+#else
         -> m (C.ResumableSource m value)
+#endif
 stream' info mgr req = do
     rsrc <- getResponse info mgr =<< liftIO (makeRequest req)
+#if MIN_VERSION_http_conduit(2,3,0)
+    return $ responseBody rsrc C..| CL.sequence sinkFromJSONIgnoreSpaces
+#else
     responseBody rsrc $=+ CL.sequence sinkFromJSONIgnoreSpaces
+#endif
   where
     sinkFromJSONIgnoreSpaces = CL.filter (not . S8.all isSpace) C.=$ sinkFromJSON
 
diff --git a/sample/userstream.hs b/sample/userstream.hs
--- a/sample/userstream.hs
+++ b/sample/userstream.hs
@@ -1,3 +1,4 @@
+{-# LANGUAGE CPP #-}
 {-# LANGUAGE OverloadedStrings #-}
 {-# LANGUAGE PatternGuards #-}
 
@@ -38,7 +39,11 @@
     mgr <- newManager tlsManagerSettings
     runResourceT $ do
         src <- stream twInfo mgr userstream
+#if MIN_VERSION_http_conduit(2,3,0)
+        C.runConduit $ src C..| CL.mapM_ (liftIO . printTL)
+#else
         src C.$$+- CL.mapM_ (liftIO . printTL)
+#endif
 
 showStatus :: AsStatus s => s -> T.Text
 showStatus s = T.concat [ s ^. user . userScreenName
@@ -84,5 +89,9 @@
         mgr <- newManager tlsManagerSettings
         runResourceT $ do
             body <- http req mgr
+#if MIN_VERSION_http_conduit(2,3,0)
+            C.runConduit $ HTTP.responseBody body C..| CB.sinkFile fname
+#else
             HTTP.responseBody body $$+- CB.sinkFile fname
+#endif
     return fname
diff --git a/twitter-conduit.cabal b/twitter-conduit.cabal
--- a/twitter-conduit.cabal
+++ b/twitter-conduit.cabal
@@ -1,5 +1,5 @@
 name:              twitter-conduit
-version:           0.2.3
+version:           0.3.0
 license:           BSD3
 license-file:      LICENSE
 author:            HATTORI Hiroki, Hideyuki Tanaka, Takahiro HIMURA
@@ -11,7 +11,7 @@
 build-type:        Custom
 homepage:          https://github.com/himura/twitter-conduit
 
-tested-with:       GHC == 7.8.4, GHC == 7.10.3, GHC == 8.0.2, GHC == 8.2.1
+tested-with:       GHC == 7.8.4, GHC == 7.10.3, GHC == 8.0.2, GHC == 8.2.2, GHC == 8.4.3
 
 description:
   This package provides bindings to Twitter's APIs (see <https://dev.twitter.com/>).
@@ -66,7 +66,7 @@
     , conduit >= 1.1
     , conduit-extra >= 1.1
     , http-types
-    , http-conduit >= 2.0 && < 2.3
+    , http-conduit >= 2.0 && < 2.4
     , http-client >= 0.3.0
     , aeson >= 0.7.0.5
     , attoparsec >= 0.10
