diff --git a/Network/Wreq.hs b/Network/Wreq.hs
--- a/Network/Wreq.hs
+++ b/Network/Wreq.hs
@@ -57,6 +57,9 @@
     -- ** PUT
     , put
     , putWith
+    -- ** PATCH
+    , patch
+    , patchWith
     -- ** DELETE
     , delete
     , deleteWith
@@ -290,6 +293,14 @@
 -- | Issue a PUT request, using the supplied 'Options'.
 putWith :: Putable a => Options -> String -> a -> IO (Response L.ByteString)
 putWith opts url payload = runRead =<< preparePut opts url payload
+
+-- | Issue a PATCH request.
+patch :: Patchable a => String -> a -> IO (Response L.ByteString)
+patch url payload = patchWith defaults url payload
+
+-- | Issue a PATCH request, using the supplied 'Options'.
+patchWith :: Patchable a => Options -> String -> a -> IO (Response L.ByteString)
+patchWith opts url payload = runRead =<< preparePatch opts url payload
 
 -- | Issue an OPTIONS request.
 --
diff --git a/Network/Wreq/Internal.hs b/Network/Wreq/Internal.hs
--- a/Network/Wreq/Internal.hs
+++ b/Network/Wreq/Internal.hs
@@ -17,6 +17,7 @@
     , runIgnore
     , prepareOptions
     , preparePut
+    , preparePatch
     , prepareDelete
     , prepareMethod
     , preparePayloadMethod
@@ -34,7 +35,7 @@
 import Network.HTTP.Client.TLS (tlsManagerSettings)
 import Network.Wreq.Internal.Lens (setHeader)
 import Network.Wreq.Internal.Types (Mgr, Req(..), Run, RunHistory)
-import Network.Wreq.Types (Auth(..), Options(..), Postable(..), Putable(..))
+import Network.Wreq.Types (Auth(..), Options(..), Postable(..), Patchable(..), Putable(..))
 import Prelude hiding (head)
 import qualified Data.ByteString as S
 import qualified Data.ByteString.Char8 as Char8
@@ -177,7 +178,7 @@
 
 preparePost :: Postable a => Options -> String -> a -> IO Req
 preparePost opts url payload = Req (manager opts) <$>
-  prepare (postPayload payload . (Lens.method .~ HTTP.methodPost)) opts url
+  prepare (fmap (Lens.method .~ HTTP.methodPost) . postPayload payload) opts url
 
 prepareMethod :: HTTP.Method -> Options -> String -> IO Req
 prepareMethod method opts url = Req (manager opts) <$>
@@ -186,7 +187,7 @@
 preparePayloadMethod :: Postable a => HTTP.Method -> Options -> String -> a
                         -> IO Req
 preparePayloadMethod method opts url payload = Req (manager opts) <$>
-  prepare (postPayload payload . (Lens.method .~ method)) opts url
+  prepare (fmap (Lens.method .~ method) . postPayload payload) opts url
 
 prepareHead :: Options -> String -> IO Req
 prepareHead = prepareMethod HTTP.methodHead
@@ -199,7 +200,11 @@
 
 preparePut :: Putable a => Options -> String -> a -> IO Req
 preparePut opts url payload = Req (manager opts) <$>
-  prepare (putPayload payload . (Lens.method .~ HTTP.methodPut)) opts url
+  prepare (fmap (Lens.method .~ HTTP.methodPut) . putPayload payload) opts url
+
+preparePatch :: Patchable a => Options -> String -> a -> IO Req
+preparePatch opts url payload = Req (manager opts) <$>
+  prepare (patchPayload payload . (Lens.method .~ HTTP.methodPatch)) opts url
 
 prepareDelete :: Options -> String -> IO Req
 prepareDelete = prepareMethod HTTP.methodDelete
diff --git a/Network/Wreq/Internal/Types.hs b/Network/Wreq/Internal/Types.hs
--- a/Network/Wreq/Internal/Types.hs
+++ b/Network/Wreq/Internal/Types.hs
@@ -23,6 +23,7 @@
     -- * Request payloads
     , Payload(..)
     , Postable(..)
+    , Patchable(..)
     , Putable(..)
     -- ** URL-encoded forms
     , FormParam(..)
@@ -161,7 +162,7 @@
   } deriving (Typeable)
 
 -- | A function that checks the result of a HTTP request and
--- potentially returns an exception.
+-- potentially throw an exception.
 type ResponseChecker = Request -> Response HTTP.BodyReader -> IO ()
 
 -- | Supported authentication types.
@@ -217,6 +218,14 @@
     postPayload = putPayload
     -- ^ Represent a value in the request body (and perhaps the
     -- headers) of a POST request.
+
+-- | A type that can be converted into a PATCH request payload.
+class Patchable a where
+  patchPayload :: a -> Request -> IO Request
+  default patchPayload :: Putable a => a -> Request -> IO Request
+  patchPayload = putPayload
+  -- ^ Represent a value in the request body (and perhaps the
+  -- headers) of a PATCH request.
 
 -- | A type that can be converted into a PUT request payload.
 class Putable a where
diff --git a/Network/Wreq/Types.hs b/Network/Wreq/Types.hs
--- a/Network/Wreq/Types.hs
+++ b/Network/Wreq/Types.hs
@@ -22,6 +22,7 @@
     -- * Request payloads
     , Payload(..)
     , Postable(..)
+    , Patchable(..)
     , Putable(..)
     -- ** URL-encoded forms
     , FormParam(..)
@@ -66,6 +67,19 @@
 instance Postable L.ByteString
 instance Postable Value
 instance Postable Encoding
+
+-- By default if the type is Putable, we use that as patchPayload
+instance Patchable Part
+instance Patchable [Part]
+instance Patchable [(S.ByteString, S.ByteString)]
+instance Patchable (S.ByteString, S.ByteString)
+instance Patchable [FormParam]
+instance Patchable FormParam
+instance Patchable Payload
+instance Patchable S.ByteString
+instance Patchable L.ByteString
+instance Patchable Value
+instance Patchable Encoding
 
 instance Putable Part where
     putPayload a = putPayload [a]
diff --git a/changelog.md b/changelog.md
--- a/changelog.md
+++ b/changelog.md
@@ -1,4 +1,9 @@
 -*- markdown -*-
+2023-03-01 0.5.4.0
+
+* Aeson 2.0 compatibility
+* Add patch request
+
 
 2020-02-08 0.5.3.3
 
diff --git a/httpbin/HttpBin/Server.hs b/httpbin/HttpBin/Server.hs
--- a/httpbin/HttpBin/Server.hs
+++ b/httpbin/HttpBin/Server.hs
@@ -9,6 +9,7 @@
 import Control.Monad.IO.Class (liftIO)
 import Data.Aeson (Value(..), eitherDecode, object, toJSON)
 import Data.Aeson.Encode.Pretty (Config(..), Indent(Spaces), defConfig, encodePretty')
+import Data.Aeson.Key (fromText)
 import Data.ByteString.Char8 (pack)
 import Data.CaseInsensitive (original)
 import Data.Maybe (catMaybes, fromMaybe)
@@ -69,7 +70,7 @@
 
 listCookies = do
   cks <- rqCookies <$> getRequest
-  let cs = [(decodeUtf8 (cookieName c),
+  let cs = [(fromText(decodeUtf8 (cookieName c)),
              toJSON (decodeUtf8 (cookieValue c))) | c <- cks]
   respond $ \obj -> return $ obj <> [("cookies", object cs)]
 
diff --git a/tests/UnitTests.hs b/tests/UnitTests.hs
--- a/tests/UnitTests.hs
+++ b/tests/UnitTests.hs
@@ -5,7 +5,6 @@
 
 module UnitTests (testWith) where
 
-import Control.Arrow (first)
 import Control.Applicative ((<$>))
 import Control.Concurrent (forkIO, killThread)
 import Control.Concurrent.MVar (newEmptyMVar, putMVar, takeMVar)
@@ -34,6 +33,7 @@
 import Test.Framework.Providers.HUnit (testCase)
 import Test.HUnit (assertBool, assertEqual, assertFailure)
 import qualified Control.Exception as E
+import qualified Data.Aeson.KeyMap as KM
 import qualified Data.CaseInsensitive as CI
 import qualified Data.HashMap.Strict as HMap
 import qualified Data.Text as T
@@ -86,8 +86,8 @@
 cikey i = _Object . toInsensitive . ix (CI.mk i)
   where
     toInsensitive = iso toCi fromCi
-    toCi = HMap.fromList . map (first CI.mk) . HMap.toList
-    fromCi = HMap.fromList . map (first CI.original) . HMap.toList
+    toCi = HMap.mapKeys CI.mk . KM.toHashMapText
+    fromCi = KM.fromHashMapText . HMap.mapKeys CI.original
 
 basicGet Verb{..} site = do
   r <- get (site "/get")
diff --git a/wreq.cabal b/wreq.cabal
--- a/wreq.cabal
+++ b/wreq.cabal
@@ -1,5 +1,5 @@
 name:                wreq
-version:             0.5.3.3
+version:             0.5.4.0
 synopsis:            An easy-to-use HTTP client library.
 description:
   .
@@ -50,7 +50,7 @@
 
 custom-setup
   setup-depends:
-    base, Cabal, cabal-doctest >=1.0.2 && <1.1
+    base < 5, Cabal < 3.9, cabal-doctest >=1.0.2 && <1.1
 
 -- disable doctests with -f-doctest
 flag doctest
@@ -139,7 +139,7 @@
     buildable: False
   else
     build-depends:
-      aeson >= 0.7,
+      aeson >= 2.0,
       aeson-pretty >= 0.8.0,
       base >= 4.5 && < 5,
       base64-bytestring,
