diff --git a/quantification.cabal b/quantification.cabal
--- a/quantification.cabal
+++ b/quantification.cabal
@@ -1,6 +1,6 @@
 cabal-version: 2.4
 name: quantification
-version: 0.6.0
+version: 0.7.0
 synopsis: Rage against the quantification
 description: Data types and typeclasses to deal with universally and existentially quantified types
 homepage: https://github.com/andrewthad/quantification#readme
@@ -21,9 +21,9 @@
   build-depends:
     , base >= 4.11.1 && < 5
     , binary >= 0.8 && < 0.11
-    , hashable >= 1.2 && < 1.4
-    , aeson >= 1.0 && < 1.6
-    , text >= 1.0 && < 2.0
+    , hashable >= 1.4 && < 1.5
+    , aeson >= 2.1 && < 2.2
+    , text >= 1.0 && < 2.1
     , path-pieces >= 0.2 && < 0.3
     , vector >= 0.11 && < 0.13
     , containers >= 0.5 && < 0.7
diff --git a/src/Data/Binary/Lifted.hs b/src/Data/Binary/Lifted.hs
--- a/src/Data/Binary/Lifted.hs
+++ b/src/Data/Binary/Lifted.hs
@@ -11,7 +11,6 @@
 import Data.Binary (Get,Put,Binary,get,put)
 import Data.Functor.Compose (Compose(..))
 import Data.Word (Word8)
-import Data.Semigroup ((<>))
 
 class Binary1 f where
   liftPut :: (a -> Put) -> f a -> Put
diff --git a/src/Data/Exists.hs b/src/Data/Exists.hs
--- a/src/Data/Exists.hs
+++ b/src/Data/Exists.hs
@@ -136,7 +136,6 @@
 import Data.Map.Strict (Map)
 import Data.Monoid.Lifted (Semigroup1(..),Monoid1(..),append1,empty1)
 import Data.Proxy (Proxy(..))
-import Data.Semigroup (Semigroup)
 import Data.Text (Text)
 import Data.Type.Equality ((:~:)(Refl),TestEquality(..))
 import Foreign.Ptr (Ptr)
@@ -145,6 +144,8 @@
 
 import qualified Data.Aeson.Encoding as Aeson
 import qualified Data.Aeson.Encoding.Internal as AEI
+import qualified Data.Aeson.Key as Key
+import qualified Data.Aeson.KeyMap as KM
 import qualified Data.Aeson.Types as Aeson
 import qualified Data.Binary as BN
 import qualified Data.HashMap.Strict as HM
@@ -184,10 +185,10 @@
   WitnessedOrderingGT :: WitnessedOrdering a b
 
 data ToJSONKeyFunctionForall f
-  = ToJSONKeyTextForall !(forall a. f a -> Text) !(forall a. f a -> Aeson.Encoding' Text)
+  = ToJSONKeyTextForall !(forall a. f a -> Aeson.Key) !(forall a. f a -> Aeson.Encoding' Aeson.Key)
   | ToJSONKeyValueForall !(forall a. f a -> Aeson.Value) !(forall a. f a -> Aeson.Encoding)
 data FromJSONKeyFunctionForeach f
-  = FromJSONKeyTextParserForeach !(forall a. Sing a -> Text -> Aeson.Parser (f a))
+  = FromJSONKeyTextParserForeach !(forall a. Sing a -> Aeson.Key -> Aeson.Parser (f a))
   | FromJSONKeyValueForeach !(forall a. Sing a -> Aeson.Value -> Aeson.Parser (f a))
 
 newtype ApplyForall f a = ApplyForall { getApplyForall :: f a }
@@ -217,7 +218,7 @@
 
 instance (Monoid1 f, Monoid a) => Monoid (ApplyLifted f a) where
   mempty = empty1 
-  mappend = liftAppend mappend
+  mappend = (<>)
 
 instance (Eq1 f, Eq a) => Eq (ApplyLifted f a) where
   (==) = eq1 
@@ -314,16 +315,16 @@
       (\xs -> Aeson.list (toEnc . Pair reify) (map getApplyForeach xs))
 
 -- this is always safe
-textEncodingToValueEncoding :: Aeson.Encoding' Text -> Aeson.Encoding' Aeson.Value
+textEncodingToValueEncoding :: Aeson.Encoding' Aeson.Key -> Aeson.Encoding' Aeson.Value
 textEncodingToValueEncoding = AEI.retagEncoding
 
 instance (FromJSONKeyForeach f, Reify a) => FromJSONKey (ApplyForeach f a) where
   fromJSONKey = case fromJSONKeyForeach of
-    FromJSONKeyTextParserForeach f -> FromJSONKeyTextParser (fmap ApplyForeach . f reify)
+    FromJSONKeyTextParserForeach f -> FromJSONKeyTextParser (fmap ApplyForeach . f reify . Key.fromText)
     FromJSONKeyValueForeach f -> FromJSONKeyValue (fmap ApplyForeach . f reify)
   fromJSONKeyList = case fromJSONKeyForeach of
     FromJSONKeyTextParserForeach f -> FromJSONKeyValue $ Aeson.withArray "ApplyForeach" $ \xs -> do
-      fmap V.toList (mapM (fmap ApplyForeach . Aeson.withText "ApplyForeach" (f reify)) xs)
+      fmap V.toList (mapM (fmap ApplyForeach . Aeson.withText "ApplyForeach" (f reify . Key.fromText)) xs)
     FromJSONKeyValueForeach f -> FromJSONKeyValue $ Aeson.withArray "ApplyForeach" $ \xs -> do
       fmap V.toList (mapM (fmap ApplyForeach . f reify) xs)
 
@@ -545,7 +546,7 @@
 instance OrdForallPoly f => Ord (Exists f) where
   compare (Exists a) (Exists b) = weakenOrdering (compareForallPoly a b)
 
-instance HashableForall f => Hashable (Exists f) where
+instance (EqForallPoly f, HashableForall f) => Hashable (Exists f) where
   hashWithSalt s (Exists a) = hashWithSaltForall s a
 
 instance ToJSONForall f => ToJSON (Exists f) where
@@ -862,13 +863,13 @@
 -- | Parse a 'Map' whose key type is higher-kinded. This only creates a valid 'Map'
 --   if the 'OrdForeach' instance agrees with the 'Ord' instance.
 parseJSONMapForeachKey :: forall k (f :: k -> Type) (a :: k) v. (FromJSONKeyForeach f, OrdForeach f, Unreify k)
-  => (Aeson.Value -> Aeson.Parser v) 
+  => (Aeson.Value -> Aeson.Parser v)
   -> Sing a
   -> Aeson.Value
   -> Aeson.Parser (Map (f a) v)
 parseJSONMapForeachKey valueParser s obj = unreify s $ case fromJSONKeyForeach of
   FromJSONKeyTextParserForeach f -> Aeson.withObject "Map k v"
-    ( fmap (M.mapKeysMonotonic getApplyForeach) . HM.foldrWithKey
+    ( fmap (M.mapKeysMonotonic getApplyForeach) . KM.foldrWithKey
       (\k v m -> M.insert
         <$> (coerce (f s k :: Aeson.Parser (f a)) :: Aeson.Parser (ApplyForeach f a)) <?> Key k
         <*> valueParser v <?> Key k
diff --git a/src/Data/Monoid/Lifted.hs b/src/Data/Monoid/Lifted.hs
--- a/src/Data/Monoid/Lifted.hs
+++ b/src/Data/Monoid/Lifted.hs
@@ -13,8 +13,7 @@
 import Data.Map.Strict (Map)
 import Data.Monoid
 import Data.Proxy (Proxy(..))
-import Data.Semigroup (Semigroup)
-import Data.Functor.Const (Const(..))
+
 import qualified Data.Functor.Product as FP
 import qualified Data.HashMap.Strict as HM
 import qualified Data.Map.Strict as M
