diff --git a/hnix.cabal b/hnix.cabal
--- a/hnix.cabal
+++ b/hnix.cabal
@@ -1,6 +1,6 @@
 cabal-version:  2.2
 name:           hnix
-version:        0.14.0.1
+version:        0.14.0.2
 synopsis:       Haskell implementation of the Nix language
 description:    Haskell implementation of the Nix language.
 category:       System, Data, Nix
@@ -404,7 +404,7 @@
     -Wall
     -fprint-potential-instances
   build-depends:
-      aeson >= 1.4.2 && < 1.6
+      aeson >= 1.4.2 && < 1.6 || >= 2.0 && < 2.1
     , array >= 0.4 && < 0.6
     , base >= 4.12 && < 5
     , base16-bytestring >= 0.1.1 && < 1.1
@@ -415,7 +415,7 @@
     , containers >= 0.5.11.0 && < 0.7
     , data-fix >= 0.3.0 && < 0.4
     , deepseq >= 1.4.3 && <1.5
-    , deriving-compat >= 0.3 && < 0.6
+    , deriving-compat >= 0.3 && < 0.7
     , directory >= 1.3.1 && < 1.4
     , exceptions >= 0.10.0 && < 0.11
     , filepath >= 1.4.2 && < 1.5
@@ -432,7 +432,7 @@
     , lens-family-core >= 1.2.2 && < 2.2
     , lens-family-th >= 0.5.0 && < 0.6
     , logict >= 0.6.0 && < 0.7 || >= 0.7.0.2 && < 0.8
-    , megaparsec >= 7.0 && < 9.1
+    , megaparsec >= 7.0 && < 9.2
     , monad-control >= 1.0.2 && < 1.1
     , monadlist >= 0.0.2 && < 0.1
     , mtl >= 2.2.2 && < 2.3
diff --git a/src/Nix/Builtins.hs b/src/Nix/Builtins.hs
--- a/src/Nix/Builtins.hs
+++ b/src/Nix/Builtins.hs
@@ -36,6 +36,10 @@
 import qualified "hashing" Crypto.Hash.SHA256  as SHA256
 import qualified "hashing" Crypto.Hash.SHA512  as SHA512
 import qualified Data.Aeson                    as A
+#if MIN_VERSION_aeson(2,0,0)
+import qualified Data.Aeson.Key                as AKM
+import qualified Data.Aeson.KeyMap             as AKM
+#endif
 import           Data.Align                     ( alignWith )
 import           Data.Array
 import           Data.Bits
@@ -1505,19 +1509,31 @@
       (A.eitherDecodeStrict' @A.Value $ encodeUtf8 jText)
 
  where
-  jsonToNValue = \case
-    A.Object m -> nvSet mempty <$> traverse jsonToNValue m
-    A.Array  l -> nvList <$> traverse jsonToNValue (V.toList l)
-    A.String s -> pure $ nvStrWithoutContext s
-    A.Number n ->
-      pure $
-        nvConstant $
-          either
-            NFloat
-            NInt
-            (floatingOrInteger n)
-    A.Bool   b -> pure $ mkNVBool b
-    A.Null     -> pure nvNull
+  jsonToNValue :: (A.Value -> m (NValue t f m))
+  jsonToNValue =
+    \case
+      A.Object m ->
+        traverseToNValue
+          (nvSet mempty)
+#if MIN_VERSION_aeson(2,0,0)
+          (M.mapKeys (coerce . AKM.toText)  $ AKM.toHashMap m)
+#else
+          (M.mapKeys coerce m)
+#endif
+      A.Array  l -> traverseToNValue nvList (V.toList l)
+      A.String s -> pure $ nvStrWithoutContext s
+      A.Number n ->
+        pure $
+          nvConstant $
+            either
+              NFloat
+              NInt
+              (floatingOrInteger n)
+      A.Bool   b -> pure $ mkNVBool b
+      A.Null     -> pure nvNull
+   where
+    traverseToNValue :: Traversable t0 => (t0 (NValue t f m) -> b) -> t0 A.Value -> m b
+    traverseToNValue f v = f <$> traverse jsonToNValue v
 
 toJSONNix :: MonadNix e t f m => NValue t f m -> m (NValue t f m)
 toJSONNix = (fmap nvStr . nvalueToJSONNixString) <=< demand
diff --git a/src/Nix/Json.hs b/src/Nix/Json.hs
--- a/src/Nix/Json.hs
+++ b/src/Nix/Json.hs
@@ -1,3 +1,4 @@
+{-# language CPP #-}
 
 module Nix.Json where
 
@@ -5,6 +6,10 @@
 import qualified Data.Aeson.Encoding           as A
 import qualified Data.HashMap.Lazy             as HM
 import qualified Data.Text.Lazy.Encoding       as TL
+#if MIN_VERSION_aeson(2,0,0)
+import qualified Data.Aeson.Key                as AKM
+import qualified Data.Aeson.KeyMap             as AKM
+#endif
 import qualified Data.Vector                   as V
 import           Nix.Atoms
 import           Nix.Effects
@@ -37,9 +42,17 @@
   NVList l -> A.Array . V.fromList <$> traverse intoJson l
   NVSet m _ ->
     maybe
-      (A.Object <$> traverse intoJson m)
+      (A.Object <$> traverse intoJson kmap)
       intoJson
-      (HM.lookup "outPath" m)
+      (lkup "outPath" kmap)
+   where
+#if MIN_VERSION_aeson(2,0,0)
+    lkup = AKM.lookup
+    kmap = AKM.fromHashMap (HM.mapKeys (AKM.fromText . coerce) m)
+#else
+    lkup = HM.lookup
+    kmap = HM.mapKeys (coerce @VarName @Text) m
+#endif
   NVPath p ->
     do
       fp <- lift $ unStorePath <$> addPath p
diff --git a/src/Nix/Utils.hs b/src/Nix/Utils.hs
--- a/src/Nix/Utils.hs
+++ b/src/Nix/Utils.hs
@@ -12,6 +12,9 @@
 import           Control.Monad.Trans.Control    ( MonadTransControl(..) )
 import qualified Data.Aeson                    as A
 import qualified Data.Aeson.Encoding           as A
+#if MIN_VERSION_aeson(2,0,0)
+import qualified Data.Aeson.KeyMap             as AKM
+#endif
 import           Data.Fix                       ( Fix(..) )
 import qualified Data.HashMap.Lazy             as M
 import qualified Data.Text                     as Text
@@ -153,8 +156,13 @@
     A.pairs
       . mconcat
       . ((\(k, v) -> A.pair k $ toEncodingSorted v) <$>)
-      . sortWith fst
-      $ M.toList m
+      . sortWith fst $
+#if MIN_VERSION_aeson(2,0,0)
+          AKM.toList
+#else
+          HM.toList
+#endif
+          m
   A.Array l -> A.list toEncodingSorted $ V.toList l
   v         -> A.toEncoding v
 
