diff --git a/rattletrap.cabal b/rattletrap.cabal
--- a/rattletrap.cabal
+++ b/rattletrap.cabal
@@ -1,7 +1,7 @@
 cabal-version: 2.2
 
 name: rattletrap
-version: 11.2.10
+version: 11.2.11
 synopsis: Parse and generate Rocket League replays.
 description: Rattletrap parses and generates Rocket League replays.
 
@@ -53,7 +53,7 @@
 
   autogen-modules: Paths_rattletrap
   build-depends:
-    , aeson ^>= 2.0.3
+    , aeson ^>= 2.0.3 || ^>= 2.1.0
     , aeson-pretty ^>= 0.8.9
     , array ^>= 0.5.4
     , bytestring ^>= 0.11.3.1
diff --git a/src/lib/Rattletrap/Schema.hs b/src/lib/Rattletrap/Schema.hs
--- a/src/lib/Rattletrap/Schema.hs
+++ b/src/lib/Rattletrap/Schema.hs
@@ -15,10 +15,12 @@
 ref :: Schema -> Json.Value
 ref s = Json.object [Json.pair "$ref" $ Text.pack "#/definitions/" <> name s]
 
-object :: [((String, Json.Value), Bool)] -> Json.Value
+object :: [((Json.Key, Json.Value), Bool)] -> Json.Value
 object xs = Json.object
   [ Json.pair "type" "object"
-  , Json.pair "properties" . Json.object $ fmap (uncurry Json.pair . fst) xs
+  , Json.pair "properties" . Json.object $ fmap
+    ((\(k, v) -> Json.pair (Json.keyToString k) v) . fst)
+    xs
   , Json.pair "required" . fmap (fst . fst) $ filter snd xs
   ]
 
diff --git a/src/lib/Rattletrap/Utility/Json.hs b/src/lib/Rattletrap/Utility/Json.hs
--- a/src/lib/Rattletrap/Utility/Json.hs
+++ b/src/lib/Rattletrap/Utility/Json.hs
@@ -1,12 +1,8 @@
 {- hlint ignore "Avoid restricted flags" -}
-{-# OPTIONS_GHC -Wno-orphans #-}
-
-{- hlint ignore "Avoid restricted extensions" -}
-{-# LANGUAGE FlexibleInstances #-}
-
 module Rattletrap.Utility.Json
   ( module Rattletrap.Utility.Json
   , Aeson.FromJSON(parseJSON)
+  , Key.Key
   , Aeson.ToJSON(toJSON)
   , Aeson.Value
   , Aeson.encode
@@ -22,28 +18,22 @@
 import qualified Data.ByteString as ByteString
 import qualified Data.ByteString.Lazy as LazyByteString
 
-toKey :: String -> Key.Key
-toKey = Key.fromString
-
-fromKey :: Key.Key -> String
-fromKey = Key.toString
-
-instance Aeson.KeyValue (String, Aeson.Value) where
-  k .= v = (fromKey k, Aeson.toJSON v)
+keyToString :: Key.Key -> String
+keyToString = Key.toString
 
 required
   :: Aeson.FromJSON value => Aeson.Object -> String -> Aeson.Parser value
-required object key = object Aeson..: toKey key
+required object key = object Aeson..: Key.fromString key
 
 optional
   :: Aeson.FromJSON value
   => Aeson.Object
   -> String
   -> Aeson.Parser (Maybe value)
-optional object key = object Aeson..:? toKey key
+optional object key = object Aeson..:? Key.fromString key
 
 pair :: (Aeson.ToJSON value, Aeson.KeyValue pair) => String -> value -> pair
-pair key value = toKey key Aeson..= value
+pair key value = Key.fromString key Aeson..= value
 
 decode :: Aeson.FromJSON a => ByteString.ByteString -> Either String a
 decode = Aeson.eitherDecodeStrict'
