diff --git a/CHANGELOG.markdown b/CHANGELOG.markdown
--- a/CHANGELOG.markdown
+++ b/CHANGELOG.markdown
@@ -1,3 +1,8 @@
+4.0
+---
+* Removed `keys` dependency
+* Now compatible with `adjunctions` 4.0
+
 3.7
 ---
 * Moved all the `Yoneda` variants around again.
diff --git a/kan-extensions.cabal b/kan-extensions.cabal
--- a/kan-extensions.cabal
+++ b/kan-extensions.cabal
@@ -1,6 +1,6 @@
 name:          kan-extensions
 category:      Data Structures, Monads, Comonads, Functors
-version:       3.7
+version:       4.0
 license:       BSD3
 cabal-version: >= 1.6
 license-file:  LICENSE
@@ -40,23 +40,19 @@
     TypeFamilies
 
   build-depends:
-    adjunctions            >= 3.0.0.1 && < 4,
-    array                  >= 0.3.0.2 && < 0.5,
-    base                   >= 4       && < 5,
-    comonad                >= 3       && < 4,
-    comonad-transformers   >= 3       && < 4,
-    comonads-fd            >= 3       && < 4,
-    containers             >= 0.4     && < 0.6,
-    contravariant          >= 0.2.0.1 && < 1,
-    distributive           >= 0.2.2   && < 1,
-    free                   >= 3       && < 4,
-    keys                   >= 3       && < 4,
-    mtl                    >= 2.0.1   && < 2.2,
-    pointed                >= 3       && < 4,
-    representable-functors >= 3.0.0.1 && < 4,
-    semigroupoids          >= 3       && < 4,
-    speculation            >= 1.4.1   && < 2,
-    transformers           >= 0.2     && < 0.4
+    adjunctions   >= 4       && < 5,
+    array         >= 0.3.0.2 && < 0.6,
+    base          >= 4       && < 5,
+    comonad       >= 4       && < 5,
+    containers    >= 0.4     && < 0.6,
+    contravariant >= 0.4.4   && < 1,
+    distributive  >= 0.2.2   && < 1,
+    free          >= 4       && < 5,
+    mtl           >= 2.0.1   && < 2.2,
+    pointed       >= 4       && < 5,
+    semigroupoids >= 4       && < 5,
+    speculation   >= 1.5.0.1 && < 2,
+    transformers  >= 0.2     && < 0.4
 
   exposed-modules:
     Control.Comonad.Density
diff --git a/src/Control/Comonad/Density.hs b/src/Control/Comonad/Density.hs
--- a/src/Control/Comonad/Density.hs
+++ b/src/Control/Comonad/Density.hs
@@ -15,7 +15,7 @@
 --
 -- The 'Density' 'Comonad' for a 'Functor' (aka the 'Comonad generated by a 'Functor')
 -- The 'Density' term dates back to Dubuc''s 1974 thesis. The term
--- '''Monad' genererated by a 'Functor''' dates back to 1972 in Street''s
+-- 'Monad' genererated by a 'Functor' dates back to 1972 in Street''s
 -- ''Formal Theory of Monads''.
 --
 -- The left Kan extension of a 'Functor' along itself (@'Lan' f f@) forms a 'Comonad'. This is
diff --git a/src/Control/Monad/Co.hs b/src/Control/Monad/Co.hs
--- a/src/Control/Monad/Co.hs
+++ b/src/Control/Monad/Co.hs
@@ -89,7 +89,6 @@
 
 -- |
 -- @
--- 'CoT' w m a ~ 'Data.Functor.KanLift.Rift' w m a
 -- 'Co' w a ~ 'Data.Functor.KanLift.Rift' w 'Identity' a
 -- @
 newtype CoT w m a = CoT { runCoT :: forall r. w (a -> m r) -> m r }
diff --git a/src/Control/Monad/Codensity.hs b/src/Control/Monad/Codensity.hs
--- a/src/Control/Monad/Codensity.hs
+++ b/src/Control/Monad/Codensity.hs
@@ -43,8 +43,7 @@
 import Data.Functor.Apply
 import Data.Functor.Kan.Ran
 import Data.Functor.Plus
-import Data.Functor.Representable
-import Data.Key
+import Data.Functor.Rep
 
 -- |
 -- @'Codensity' f@ is the Monad generated by taking the right Kan extension
@@ -173,7 +172,7 @@
 -- codensityToComposedRep = 'ranToComposedRep' . 'codensityToRan'
 -- @
 
-codensityToComposedRep :: Representable u => Codensity u a -> u (Key u, a)
+codensityToComposedRep :: Representable u => Codensity u a -> u (Rep u, a)
 codensityToComposedRep (Codensity f) = f (\a -> tabulate $ \e -> (e, a))
 {-# INLINE codensityToComposedRep #-}
 
@@ -182,7 +181,7 @@
 -- @
 -- 'composedRepToCodensity' = 'ranToCodensity' . 'composedRepToRan'
 -- @
-composedRepToCodensity :: Representable u => u (Key u, a) -> Codensity u a
+composedRepToCodensity :: Representable u => u (Rep u, a) -> Codensity u a
 composedRepToCodensity hfa = Codensity $ \k -> fmap (\(e, a) -> index (k a) e) hfa
 {-# INLINE composedRepToCodensity #-}
 
diff --git a/src/Data/Functor/Contravariant/Coyoneda.hs b/src/Data/Functor/Contravariant/Coyoneda.hs
--- a/src/Data/Functor/Contravariant/Coyoneda.hs
+++ b/src/Data/Functor/Contravariant/Coyoneda.hs
@@ -29,9 +29,8 @@
 import Control.Arrow
 import Data.Functor.Contravariant
 import Data.Functor.Contravariant.Adjunction
-import Data.Functor.Contravariant.Representable
+import Data.Functor.Contravariant.Rep
 
-type instance Value (Coyoneda f) = Value f
 
 -- | A 'Contravariant' functor (aka presheaf) suitable for Yoneda reduction.
 --
@@ -43,17 +42,14 @@
   contramap f (Coyoneda g m) = Coyoneda (g.f) m
   {-# INLINE contramap #-}
 
-instance Valued f => Valued (Coyoneda f) where
-  contramapWithValue beav (Coyoneda ac fc) = Coyoneda (left ac . beav) (contramapWithValue id fc)
-  {-# INLINE contramapWithValue #-}
-
-instance Coindexed f => Coindexed (Coyoneda f) where
-  coindex (Coyoneda ab fb) a = coindex fb (ab a)
-  {-# INLINE coindex #-}
-
 instance Representable f => Representable (Coyoneda f) where
-  contrarep = liftCoyoneda . contrarep
-  {-# INLINE contrarep #-}
+  type Rep (Coyoneda f) = Rep f
+  tabulate = liftCoyoneda . tabulate
+  {-# INLINE tabulate #-}
+  index (Coyoneda ab fb) a = index fb (ab a)
+  {-# INLINE index #-}
+  contramapWithRep beav (Coyoneda ac fc) = Coyoneda (left ac . beav) (contramapWithRep id fc)
+  {-# INLINE contramapWithRep #-}
 
 instance Adjunction f g => Adjunction (Coyoneda f) (Coyoneda g) where
   leftAdjunct f = liftCoyoneda . leftAdjunct (lowerCoyoneda . f)
diff --git a/src/Data/Functor/Contravariant/Yoneda.hs b/src/Data/Functor/Contravariant/Yoneda.hs
--- a/src/Data/Functor/Contravariant/Yoneda.hs
+++ b/src/Data/Functor/Contravariant/Yoneda.hs
@@ -24,7 +24,7 @@
 
 import Data.Functor.Contravariant
 import Data.Functor.Contravariant.Adjunction
-import Data.Functor.Contravariant.Representable
+import Data.Functor.Contravariant.Rep
 
 -- | Yoneda embedding for a presheaf
 newtype Yoneda f a = Yoneda { runYoneda :: forall r. (r -> a) -> f r }
@@ -48,19 +48,14 @@
   contramap ab (Yoneda m) = Yoneda (m . fmap ab)
   {-# INLINE contramap #-}
 
-type instance Value (Yoneda f) = Value f
-
-instance Valued f => Valued (Yoneda f) where
-  contramapWithValue beav = liftYoneda . contramapWithValue beav . lowerYoneda
-  {-# INLINE contramapWithValue #-}
-
-instance Coindexed f => Coindexed (Yoneda f) where
-  coindex m a = coindex (lowerYoneda m) a
-  {-# INLINE coindex #-}
-
 instance Representable f => Representable (Yoneda f) where
-  contrarep = liftYoneda . contrarep
-  {-# INLINE contrarep #-}
+  type Rep (Yoneda f) = Rep f
+  tabulate = liftYoneda . tabulate
+  {-# INLINE tabulate #-}
+  index m a = index (lowerYoneda m) a
+  {-# INLINE index #-}
+  contramapWithRep beav = liftYoneda . contramapWithRep beav . lowerYoneda
+  {-# INLINE contramapWithRep #-}
 
 instance Adjunction f g => Adjunction (Yoneda f) (Yoneda g) where
   leftAdjunct f = liftYoneda . leftAdjunct (lowerYoneda . f)
diff --git a/src/Data/Functor/Coyoneda.hs b/src/Data/Functor/Coyoneda.hs
--- a/src/Data/Functor/Coyoneda.hs
+++ b/src/Data/Functor/Coyoneda.hs
@@ -45,8 +45,7 @@
 import Data.Functor.Kan.Lan
 import Data.Functor.Kan.Lift
 import Data.Functor.Plus
-import Data.Functor.Representable
-import Data.Key
+import Data.Functor.Rep
 import Data.Foldable
 import Data.Traversable
 import Data.Semigroup.Foldable
@@ -93,12 +92,6 @@
   fmap f (Coyoneda g v) = Coyoneda (f . g) v
   {-# INLINE fmap #-}
 
-type instance Key (Coyoneda f) = Key f
-
-instance Keyed f => Keyed (Coyoneda f) where
-  mapWithKey f (Coyoneda k a) = Coyoneda id $ mapWithKey (\x -> f x . k) a
-  {-# INLINE mapWithKey #-}
-
 instance Apply f => Apply (Coyoneda f) where
   m <.> n = liftCoyoneda $ lowerCoyoneda m <.> lowerCoyoneda n
   {-# INLINE (<.>) #-}
@@ -109,14 +102,6 @@
   m <*> n = liftCoyoneda $ lowerCoyoneda m <*> lowerCoyoneda n
   {-# INLINE (<*>) #-}
 
-instance Zip f => Zip (Coyoneda f) where
-  zipWith f m n = liftCoyoneda $ zipWith f (lowerCoyoneda m) (lowerCoyoneda n)
-  {-# INLINE zipWith #-}
-
-instance ZipWithKey f => ZipWithKey (Coyoneda f) where
-  zipWithKey f m n = liftCoyoneda $ zipWithKey f (lowerCoyoneda m) (lowerCoyoneda n)
-  {-# INLINE zipWithKey #-}
-
 instance Alternative f => Alternative (Coyoneda f) where
   empty = liftCoyoneda empty
   {-# INLINE empty #-}
@@ -155,17 +140,12 @@
   m `mplus` n = lift $ lowerM m `mplus` lowerM n
   {-# INLINE mplus #-}
 
-instance (Functor f, Lookup f) => Lookup (Coyoneda f) where
-  lookup k f = lookup k (lowerCoyoneda f)
-  {-# INLINE lookup #-}
-
-instance (Functor f, Indexable f) => Indexable (Coyoneda f) where
-  index = index . lowerCoyoneda
-  {-# INLINE index #-}
-
 instance Representable f => Representable (Coyoneda f) where
+  type Rep (Coyoneda f) = Rep f
   tabulate = liftCoyoneda . tabulate
   {-# INLINE tabulate #-}
+  index = index . lowerCoyoneda
+  {-# INLINE index #-}
 
 instance Extend w => Extend (Coyoneda w) where
   extended k (Coyoneda f v) = Coyoneda id $ extended (k . Coyoneda f) v
@@ -185,18 +165,10 @@
   foldMap f (Coyoneda k a) = foldMap (f . k) a
   {-# INLINE foldMap #-}
 
-instance FoldableWithKey f => FoldableWithKey (Coyoneda f) where
-  foldMapWithKey f (Coyoneda k a) = foldMapWithKey (\x -> f x . k) a
-  {-# INLINE foldMapWithKey #-}
-
 instance Foldable1 f => Foldable1 (Coyoneda f) where
   foldMap1 f (Coyoneda k a) = foldMap1 (f . k) a
   {-# INLINE foldMap1 #-}
 
-instance FoldableWithKey1 f => FoldableWithKey1 (Coyoneda f) where
-  foldMapWithKey1 f (Coyoneda k a) = foldMapWithKey1 (\x -> f x . k) a
-  {-# INLINE foldMapWithKey1 #-}
-
 instance Traversable f => Traversable (Coyoneda f) where
   traverse f (Coyoneda k a) = Coyoneda id <$> traverse (f . k) a
   {-# INLINE traverse #-}
@@ -204,14 +176,6 @@
 instance Traversable1 f => Traversable1 (Coyoneda f) where
   traverse1 f (Coyoneda k a) = Coyoneda id <$> traverse1 (f . k) a
   {-# INLINE traverse1 #-}
-
-instance TraversableWithKey f => TraversableWithKey (Coyoneda f) where
-  traverseWithKey f (Coyoneda k a) = Coyoneda id <$> traverseWithKey (\x -> f x . k) a
-  {-# INLINE traverseWithKey #-}
-
-instance TraversableWithKey1 f => TraversableWithKey1 (Coyoneda f) where
-  traverseWithKey1 f (Coyoneda k a) = Coyoneda id <$> traverseWithKey1 (\x -> f x . k) a
-  {-# INLINE traverseWithKey1 #-}
 
 instance Distributive f => Distributive (Coyoneda f) where
   collect f = liftCoyoneda . collect (lowerCoyoneda . f)
diff --git a/src/Data/Functor/Kan/Lift.hs b/src/Data/Functor/Kan/Lift.hs
--- a/src/Data/Functor/Kan/Lift.hs
+++ b/src/Data/Functor/Kan/Lift.hs
@@ -35,8 +35,7 @@
 import Data.Functor.Composition
 import Data.Functor.Compose
 import Data.Functor.Identity
-import Data.Functor.Representable
-import Data.Key
+import Data.Functor.Rep
 
 -- * Left Kan Lift
 
@@ -113,11 +112,11 @@
 -- 'repToLift' . 'liftToRep' ≡ 'id'
 -- 'liftToRep' . 'repToLift' ≡ 'id'
 -- @
-repToLift :: Representable u => Key u -> a -> Lift u Identity a
+repToLift :: Representable u => Rep u -> a -> Lift u Identity a
 repToLift e a = Lift $ \k -> index (k (Identity a)) e
 {-# INLINE repToLift #-}
 
-liftToRep :: Representable u => Lift u Identity a -> (Key u, a)
+liftToRep :: Representable u => Lift u Identity a -> (Rep u, a)
 liftToRep (Lift m) = m $ \(Identity a) -> tabulate $ \e -> (e, a)
 {-# INLINE liftToRep #-}
 
@@ -142,10 +141,10 @@
 -- 'liftToComposedRep' . 'composedRepToLift' ≡ 'id'
 -- 'composedRepToLift' . 'liftToComposedRep' ≡ 'id'
 -- @
-liftToComposedRep :: (Functor h, Representable u) => Lift u h a -> (Key u, h a)
+liftToComposedRep :: (Functor h, Representable u) => Lift u h a -> (Rep u, h a)
 liftToComposedRep (Lift m) = decompose $ m $ \h -> tabulate $ \e -> Compose (e, h)
 {-# INLINE liftToComposedRep #-}
 
-composedRepToLift :: Representable u => Key u -> h a -> Lift u h a
+composedRepToLift :: Representable u => Rep u -> h a -> Lift u h a
 composedRepToLift e ha = Lift $ \h2uz -> index (h2uz ha) e
 {-# INLINE composedRepToLift #-}
diff --git a/src/Data/Functor/Kan/Ran.hs b/src/Data/Functor/Kan/Ran.hs
--- a/src/Data/Functor/Kan/Ran.hs
+++ b/src/Data/Functor/Kan/Ran.hs
@@ -29,8 +29,7 @@
 import Data.Functor.Adjunction
 import Data.Functor.Composition
 import Data.Functor.Identity
-import Data.Functor.Representable
-import Data.Key
+import Data.Functor.Rep
 
 -- | The right Kan extension of a 'Functor' h along a 'Functor' g.
 --
@@ -150,18 +149,18 @@
 gran (Ran f) = f id
 {-# INLINE gran #-}
 
-repToRan :: Representable u => Key u -> a -> Ran u Identity a
+repToRan :: Representable u => Rep u -> a -> Ran u Identity a
 repToRan e a = Ran $ \k -> Identity $ index (k a) e
 {-# INLINE repToRan #-}
 
-ranToRep :: Representable u => Ran u Identity a -> (Key u, a)
+ranToRep :: Representable u => Ran u Identity a -> (Rep u, a)
 ranToRep (Ran f) = runIdentity $ f (\a -> tabulate $ \e -> (e, a))
 {-# INLINE ranToRep #-}
 
-ranToComposedRep :: Representable u => Ran u h a -> h (Key u, a)
+ranToComposedRep :: Representable u => Ran u h a -> h (Rep u, a)
 ranToComposedRep (Ran f) = f (\a -> tabulate $ \e -> (e, a))
 {-# INLINE ranToComposedRep #-}
 
-composedRepToRan :: (Representable u, Functor h) => h (Key u, a) -> Ran u h a
+composedRepToRan :: (Representable u, Functor h) => h (Rep u, a) -> Ran u h a
 composedRepToRan hfa = Ran $ \k -> fmap (\(e, a) -> index (k a) e) hfa
 {-# INLINE composedRepToRan #-}
diff --git a/src/Data/Functor/Kan/Rift.hs b/src/Data/Functor/Kan/Rift.hs
--- a/src/Data/Functor/Kan/Rift.hs
+++ b/src/Data/Functor/Kan/Rift.hs
@@ -97,8 +97,6 @@
 --
 -- An alternative way to view that is to note that whenever @f@ is a left adjoint then @f -| 'Rift' f 'Identity'@, and since @'Rift' f f@ is isomorphic to @'Rift' f 'Identity' (f a)@, this is the 'Monad' formed by the adjunction.
 --
--- @'Rift' w f ~ 'Control.Monad.Co.CoT' w f@ can be a 'Monad' for any 'Comonad' @w@.
---
 -- @'Rift' 'Identity' m@ can be a 'Monad' for any 'Monad' @m@, as it is isomorphic to @'Yoneda' m@.
 
 newtype Rift g h a =
diff --git a/src/Data/Functor/Yoneda.hs b/src/Data/Functor/Yoneda.hs
--- a/src/Data/Functor/Yoneda.hs
+++ b/src/Data/Functor/Yoneda.hs
@@ -59,8 +59,7 @@
 import Data.Functor.Kan.Ran
 import Data.Functor.Kan.Rift
 import Data.Functor.Plus
-import Data.Functor.Representable
-import Data.Key
+import Data.Functor.Rep
 import Data.Semigroup.Foldable
 import Data.Semigroup.Traversable
 import Data.Traversable
@@ -141,11 +140,6 @@
 instance Functor (Yoneda f) where
   fmap f m = Yoneda (\k -> runYoneda m (k . f))
 
-type instance Key (Yoneda f) = Key f
-
-instance Keyed f => Keyed (Yoneda f) where
-  mapWithKey f = liftYoneda . mapWithKey f . lowerYoneda
-
 instance Apply f => Apply (Yoneda f) where
   Yoneda m <.> Yoneda n = Yoneda (\f -> m (f .) <.> n id)
 
@@ -153,47 +147,25 @@
   pure a = Yoneda (\f -> pure (f a))
   Yoneda m <*> Yoneda n = Yoneda (\f -> m (f .) <*> n id)
 
-instance Zip f => Zip (Yoneda f) where
-  zipWith f (Yoneda m) (Yoneda n) = liftYoneda $ zipWith f (m id) (n id)
-
-instance ZipWithKey f => ZipWithKey (Yoneda f) where
-  zipWithKey f (Yoneda m) (Yoneda n) = liftYoneda $ zipWithKey f (m id) (n id)
-
 instance Foldable f => Foldable (Yoneda f) where
   foldMap f = foldMap f . lowerYoneda
 
 instance Foldable1 f => Foldable1 (Yoneda f) where
   foldMap1 f = foldMap1 f . lowerYoneda
 
-instance FoldableWithKey f => FoldableWithKey (Yoneda f) where
-  foldMapWithKey f = foldMapWithKey f . lowerYoneda
-
-instance FoldableWithKey1 f => FoldableWithKey1 (Yoneda f) where
-  foldMapWithKey1 f = foldMapWithKey1 f . lowerYoneda
-
 instance Traversable f => Traversable (Yoneda f) where
   traverse f = fmap liftYoneda . traverse f . lowerYoneda
 
-instance TraversableWithKey f => TraversableWithKey (Yoneda f) where
-  traverseWithKey f = fmap liftYoneda . traverseWithKey f . lowerYoneda
-
 instance Traversable1 f => Traversable1 (Yoneda f) where
   traverse1 f = fmap liftYoneda . traverse1 f . lowerYoneda
 
-instance TraversableWithKey1 f => TraversableWithKey1 (Yoneda f) where
-  traverseWithKey1 f = fmap liftYoneda . traverseWithKey1 f . lowerYoneda
-
 instance Distributive f => Distributive (Yoneda f) where
   collect f = liftYoneda . collect (lowerYoneda . f)
 
-instance Indexable f => Indexable (Yoneda f) where
-  index = index . lowerYoneda
-
-instance Lookup f => Lookup (Yoneda f) where
-  lookup i = lookup i . lowerYoneda
-
 instance Representable g => Representable (Yoneda g) where
+  type Rep (Yoneda f) = Rep f
   tabulate = liftYoneda . tabulate
+  index = index . lowerYoneda
 
 instance Adjunction f g => Adjunction (Yoneda f) (Yoneda g) where
   unit = liftYoneda . fmap liftYoneda . unit
