diff --git a/CHANGELOG.md b/CHANGELOG.md
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,11 @@
 # microlens-aeson
 
+## 2.4.0 (2021-10-21)
+
+#### Changed
+
+- `aeson-2.0` is now the minimum required version.
+
 ## 2.3.1 (2020-07-19)
 
 #### Fixed
@@ -7,44 +13,56 @@
 - Test suite fixed to succeed deterministically on 32-bit machines.
 
 ## 2.3.0.3
+
 - Readd 7.10 support. Forgive the spam.
 
 ## 2.3.0.2
+
 - Bumping bounds, cleaning code.
 
 ## 2.3.0.1
+
 - Enable compilation with GHC `7.8` (`base-4.7`). Only when this version of
   `base` is used does our type `Primitive` lose its `Hashable` instance, due to
   a lack of `DeriveAnyClass`. Otherwise, the API is unchanged from
   `microlens-aeson-2.3.0`.
 
 ## 2.2.0
+
 - Various fixes to dependency version bounds
 
 ## 2.1.0
-* Restored original `AsJSON` and `_JSON` typing
-* Bumped `microlens` dep max
 
+- Restored original `AsJSON` and `_JSON` typing
+- Bumped `microlens` dep max
+
 ## 2.0.0
-* Complete conversion to `microlens`
-* All `Prism` are now `Traversal`
 
+- Complete conversion to `microlens`
+- All `Prism` are now `Traversal`
+
 ## 1.0.0.5
-* Fix tests to work against vector-0.11
-* Documentation fixes
-* No functional changes since 1.0.0.4
 
+- Fix tests to work against vector-0.11
+- Documentation fixes
+- No functional changes since 1.0.0.4
+
 ## 1.0.0.3
-* Move lens upper bound to < 5 like the other packages in the family
 
+- Move lens upper bound to < 5 like the other packages in the family
+
 ## 1
-* Module migrated from lens package to Data.Aeson.Lens
 
+- Module migrated from lens package to Data.Aeson.Lens
+
 ## 0.1.2
-* Added `members` and `values`
 
+- Added `members` and `values`
+
 ## 0.1.1
-* Broadened dependencies
 
+- Broadened dependencies
+
 ## 0.1
-* Repository initialized
+
+- Repository initialized
diff --git a/microlens-aeson.cabal b/microlens-aeson.cabal
--- a/microlens-aeson.cabal
+++ b/microlens-aeson.cabal
@@ -1,6 +1,6 @@
 cabal-version:      2.2
 name:               microlens-aeson
-version:            2.3.1
+version:            2.4.0
 synopsis:           Law-abiding lenses for Aeson, using microlens.
 description:        Law-abiding lenses for Aeson, using microlens.
 category:           Numeric
@@ -24,7 +24,7 @@
   default-language: Haskell2010
   ghc-options:      -Wall -fwarn-incomplete-record-updates
   build-depends:
-    , aeson                 >=0.7
+    , aeson                 >=2.0
     , base                  >=4.7   && <5
     , bytestring
     , deepseq
diff --git a/src/Lens/Micro/Aeson.hs b/src/Lens/Micro/Aeson.hs
--- a/src/Lens/Micro/Aeson.hs
+++ b/src/Lens/Micro/Aeson.hs
@@ -10,7 +10,7 @@
 
 -- |
 -- Module    :  Lens.Micro.Aeson
--- Copyright :  (c) Colin Woodbury 2015 - 2018, (c) Edward Kmett 2013-2014, (c) Paul Wilson 2012
+-- Copyright :  (c) Colin Woodbury 2015-2021, (c) Edward Kmett 2013-2014, (c) Paul Wilson 2012
 -- License   :  BSD3
 -- Maintainer:  Colin Woodbury <colingw@gmail.com>
 --
@@ -42,6 +42,7 @@
 import           Data.Traversable (traverse)
 #endif
 import           Data.Aeson
+import qualified Data.Aeson.KeyMap as KM
 import           Data.Aeson.Parser (value)
 import           Data.Attoparsec.ByteString.Lazy (maybeResult, parse)
 import qualified Data.ByteString as Strict
@@ -284,8 +285,9 @@
   -- Nothing
   _Object :: Traversal' t (HashMap Text Value)
   _Object = _Value . trav
-    where trav f (Object o) = Object <$> f o
-          trav _ v          = pure v
+    where
+      trav f (Object o) = Object . KM.fromHashMapText <$> f (KM.toHashMapText o)
+      trav _ v          = pure v
   {-# INLINE _Object #-}
 
   _Array :: Traversal' t (Vector Value)
diff --git a/src/Lens/Micro/Aeson/Internal.hs b/src/Lens/Micro/Aeson/Internal.hs
--- a/src/Lens/Micro/Aeson/Internal.hs
+++ b/src/Lens/Micro/Aeson/Internal.hs
@@ -1,12 +1,13 @@
-{-# LANGUAGE CPP               #-}
-{-# LANGUAGE FlexibleInstances #-}
-{-# LANGUAGE TypeFamilies      #-}
+{-# LANGUAGE CPP                   #-}
+{-# LANGUAGE FlexibleInstances     #-}
+{-# LANGUAGE MultiParamTypeClasses #-}
+{-# LANGUAGE TypeFamilies          #-}
 
 {-# OPTIONS_GHC -fno-warn-orphans #-}
 
 -- |
 -- Module    :  Lens.Micro.Aeson.Internal
--- Copyright :  (c) Colin Woodbury 2015, (c) Edward Kmett 2013-2014, (c) Paul Wilson 2012
+-- Copyright :  (c) Colin Woodbury 2015-2021, (c) Edward Kmett 2013-2014, (c) Paul Wilson 2012
 -- License   :  BSD3
 -- Maintainer:  Colin Woodbury <colingw@gmail.com>
 --
@@ -18,13 +19,15 @@
 module Lens.Micro.Aeson.Internal where
 
 #if !MIN_VERSION_base(4,8,0)
-import Control.Applicative
+import           Control.Applicative
 #endif
-import Data.Aeson (Value(..))
-import Data.HashMap.Lazy as HashMap
-import Data.Text (Text)
-import Data.Vector as V
-import Lens.Micro.Internal
+import           Data.Aeson (Value(..))
+import qualified Data.Aeson.Key as Key
+import qualified Data.Aeson.KeyMap as KM
+import           Data.HashMap.Lazy as HashMap
+import           Data.Text (Text)
+import           Data.Vector as V
+import           Lens.Micro.Internal
 
 ---
 
@@ -35,7 +38,7 @@
 -- | Can only index into the contents of an `Object`,
 -- which is a `HashMap`.
 instance Ixed Value where
-  ix i f (Object o) = Object <$> ix i f o
+  ix i f (Object o) = Object <$> ix (Key.fromText i) f o
   ix _ _ v          = pure v
   {-# INLINE ix #-}
 
@@ -60,3 +63,22 @@
     | 0 <= i && i < V.length v = (\a -> v V.// [(i, a)]) <$> f (v V.! i)
     | otherwise = pure v
   {-# INLINE ix #-}
+
+-- Thu Oct 21 11:49:16 2021
+-- Adapted from lens-aeson to account for the aeson-2 update.
+
+type instance Index (KM.KeyMap v) = Key.Key
+
+type instance IxValue (KM.KeyMap v) = v
+
+instance Ixed (KM.KeyMap v) where
+  ix i f m = case KM.lookup i m of
+    Nothing -> pure m
+    Just v  -> (\v' -> KM.insert i v' m) <$> f v
+
+instance At (KM.KeyMap v) where
+  at k f = KM.alterF f k
+
+instance Each (KM.KeyMap a) (KM.KeyMap b) a b where
+  each = traversed
+  {-# INLINE each #-}
diff --git a/test/Test.hs b/test/Test.hs
--- a/test/Test.hs
+++ b/test/Test.hs
@@ -1,6 +1,7 @@
 module Main where
 
 import           Data.Aeson
+import qualified Data.Aeson.KeyMap as KM
 import qualified Data.HashMap.Strict as HMS
 import qualified Data.Text as T
 import           Lens.Micro
@@ -41,7 +42,7 @@
     , testCase "" $ ("{\"a\": \"xyz\", \"b\": null}" ^? key (T.pack "b") . _Null) @?= Just ()
     , testCase "" $ ("{\"a\": \"xyz\", \"b\": null}" ^? key (T.pack "a") . _Null) @?= Nothing
     , testCase "" $ ("{\"a\": \"xyz\", \"b\": null}" ^? key (T.pack "a") . nonNull) @?= Just (String $ T.pack "xyz")
-    , testCase "" $ ("{\"a\": {}, \"b\": null}" ^? key (T.pack "a") . nonNull) @?= Just (Object (HMS.fromList []))
+    , testCase "" $ ("{\"a\": {}, \"b\": null}" ^? key (T.pack "a") . nonNull) @?= Just (Object . KM.fromHashMapText $ HMS.fromList [])
     , testCase "" $ ("{\"a\": \"xyz\", \"b\": null}" ^? key (T.pack "b") . nonNull) @?= Nothing
     ]
   , testGroup "Non-primitive Traversals"
