diff --git a/CHANGELOG.md b/CHANGELOG.md
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,10 @@
 # Revision history for deriving-trans
 
+## 0.5.2.0 *17 Jan 2023*
+
+* Add optional dependency `primitive`.
+* Add `MonadPrim` instances to `Elevator` and `ComposeT`.
+
 ## 0.5.1.0 *11 Jan 2023*
 
 * Introduce cabal flags `exceptions`, `mtl` and `unliftio`.
diff --git a/deriving-trans.cabal b/deriving-trans.cabal
--- a/deriving-trans.cabal
+++ b/deriving-trans.cabal
@@ -1,43 +1,49 @@
-cabal-version:       3.0
-name:                deriving-trans
-version:             0.5.1.0
-synopsis:            Derive instances for monad transformer stacks
-description:         Implementing instances for monad transformer stacks can be tedious.
-                     <https://hackage.haskell.org/package/mtl mtl> defines each instance for each
-                     transfomer, but this can be avoided.
+cabal-version: 3.0
+name: deriving-trans
+version: 0.5.2.0
+synopsis: Derive instances for monad transformer stacks
+description:
+  Implementing instances for monad transformer stacks can be tedious.
+  <https://hackage.haskell.org/package/mtl mtl> defines each instance for each
+  transfomer, but this can be avoided.
 
-                     'Elevator' let's you access instances of the underlying monad of a transformer.
-                     Composing transformers with 'ComposeT' brings instances into scope during the
-                     initialization of a transformer stack.
+  'Elevator' let's you access instances of the underlying monad of a transformer.
+  Composing transformers with 'ComposeT' brings instances into scope during the
+  initialization of a transformer stack.
 
-                     'Elevator' can be used with DerivingVia to select a specific transformer to
-                     derive instances for a transformer stack.
-                     'ComposeT' composes transformers and accumulates instances in a transformer
-                     stack.
-license:             BSD-3-Clause
-license-file:        LICENSE
-author:              Felix Springer
-maintainer:          felixspringer149@gmail.com
-homepage:            https://github.com/jumper149/deriving-trans
-bug-reports:         https://github.com/jumper149/deriving-trans/issues
-category:            Control
-build-type:          Simple
-extra-source-files:  CHANGELOG.md
+  'Elevator' can be used with DerivingVia to select a specific transformer to
+  derive instances for a transformer stack.
+  'ComposeT' composes transformers and accumulates instances in a transformer
+  stack.
+license: BSD-3-Clause
+license-file: LICENSE
+author: Felix Springer
+maintainer: felixspringer149@gmail.com
+homepage: https://github.com/jumper149/deriving-trans
+bug-reports: https://github.com/jumper149/deriving-trans/issues
+category: Control
+build-type: Simple
+extra-source-files: CHANGELOG.md
 
 flag exceptions
   default: True
   description:
-    Implement instances for 'Control.Monad.Catch.MonadThrow' and 'Control.Monad.Catch.MonadCatch'.
+    Implement instances for 'MonadThrow' and 'MonadCatch'.
 
 flag mtl
   default: True
   description:
     Implement instances for mtl's type classes.
 
+flag primitive
+  default: True
+  description:
+    Implement instances for `PrimMonad`.
+
 flag unliftio
   default: True
   description:
-    Implement instances for 'Control.Monad.IO.Unlift.MonadUnliftIO'.
+    Implement instances for 'MonadUnliftIO'.
 
 library
   exposed-modules:
@@ -59,6 +65,9 @@
   if flag(mtl)
     build-depends:
       , mtl
+  if flag(primitive)
+    build-depends:
+      , primitive
   if flag(unliftio)
     build-depends:
       , unliftio-core
@@ -85,6 +94,7 @@
     RankNTypes
     StandaloneDeriving
     StandaloneKindSignatures
+    TupleSections
     TypeApplications
     TypeFamilies
     TypeOperators
diff --git a/src/Control/Monad/Trans/Compose.hs b/src/Control/Monad/Trans/Compose.hs
--- a/src/Control/Monad/Trans/Compose.hs
+++ b/src/Control/Monad/Trans/Compose.hs
@@ -1,5 +1,6 @@
 {-# LANGUAGE CPP #-}
 {-# LANGUAGE QuantifiedConstraints #-}
+{-# LANGUAGE UnboxedTuples #-}
 {-# LANGUAGE UndecidableInstances #-}
 
 module Control.Monad.Trans.Compose where
@@ -35,6 +36,10 @@
 import Control.Monad.Writer.Class
 #endif
 
+#if defined(VERSION_primitive)
+import Control.Monad.Primitive
+#endif
+
 #if defined(VERSION_unliftio_core)
 import Control.Monad.IO.Unlift
 #endif
@@ -297,6 +302,17 @@
     ( Monad (t2 m)
     , Monoid w
     ) => MonadWriter w (ComposeT (ST.RWST r w s) t2 m)
+#endif
+
+#if defined(VERSION_primitive)
+-- | Elevated to @m@.
+deriving via Elevator (ComposeT t1 t2) m
+  instance
+    ( Monad (t1 (t2 m))
+    , MonadTrans (ComposeT t1 t2)
+    , PrimMonad m
+    ) =>
+    PrimMonad (ComposeT t1 t2 m)
 #endif
 
 #if defined(VERSION_unliftio_core)
diff --git a/src/Control/Monad/Trans/Elevator.hs b/src/Control/Monad/Trans/Elevator.hs
--- a/src/Control/Monad/Trans/Elevator.hs
+++ b/src/Control/Monad/Trans/Elevator.hs
@@ -1,7 +1,6 @@
 {-# LANGUAGE CPP #-}
 {-# LANGUAGE QuantifiedConstraints #-}
 {-# LANGUAGE UndecidableInstances #-}
-{-# LANGUAGE TupleSections #-}
 
 module Control.Monad.Trans.Elevator where
 
@@ -29,6 +28,10 @@
 import Control.Monad.Writer.Class
 #endif
 
+#if defined(VERSION_primitive)
+import Control.Monad.Primitive
+#endif
+
 #if defined(VERSION_unliftio_core)
 import Control.Monad.IO.Unlift
 #endif
@@ -125,6 +128,12 @@
   listen tma = liftWith (\ runT -> listen $ runT tma) >>= \ (sta, w) ->
     (, w) <$> restoreT (pure sta)
   pass tma = lift . pass . pure =<< tma
+#endif
+
+#if defined(VERSION_primitive)
+instance (Monad (t m), MonadTrans t, PrimMonad m) => PrimMonad (Elevator t m) where
+  type PrimState (Elevator t m) = PrimState m
+  primitive = lift . primitive
 #endif
 
 #if defined(VERSION_unliftio_core)
