diff --git a/ChangeLog.md b/ChangeLog.md
--- a/ChangeLog.md
+++ b/ChangeLog.md
@@ -1,3 +1,7 @@
+## 0.10.5
+
+* Export `Data.Mutable`
+
 ## 0.10.4
 
 * Expose all of Data.Functor
diff --git a/ClassyPrelude.hs b/ClassyPrelude.hs
--- a/ClassyPrelude.hs
+++ b/ClassyPrelude.hs
@@ -30,6 +30,7 @@
     , orElseSTM
     , checkSTM
     , module Data.IORef.Lifted
+    , module Data.Mutable
       -- ** Primitive (exported since 0.9.4)
     , PrimMonad
     , PrimState
@@ -174,6 +175,7 @@
 import Control.Concurrent.STM hiding (atomically, always, alwaysSucceeds, retry, orElse, check)
 import qualified Control.Concurrent.STM as STM
 import Data.IORef.Lifted
+import Data.Mutable
 import qualified Data.Monoid as Monoid
 import Data.Traversable (Traversable (..), for, forM)
 import Data.Foldable (Foldable)
@@ -232,14 +234,14 @@
 -- | Convert a character to lower case.
 --
 -- Character-based case conversion is lossy in comparison to string-based 'Data.MonoTraversable.toLower'.
--- For instance, \'&#x130;\' will be converted to \'i\', instead of \"i&#x307;\".
+-- For instance, &#x130; will be converted to i, instead of i&#x307;.
 charToLower :: Char -> Char
 charToLower = Char.toLower
 
 -- | Convert a character to upper case.
 --
 -- Character-based case conversion is lossy in comparison to string-based 'Data.MonoTraversable.toUpper'.
--- For instance, \'&#xdf;\' won't be converted to \"SS\".
+-- For instance, &#xdf; won't be converted to SS.
 charToUpper :: Char -> Char
 charToUpper = Char.toUpper
 
@@ -340,12 +342,12 @@
 {-# INLINE (++) #-}
 
 infixl 9 \\{-This comment teaches CPP correct behaviour -}
--- | An alias for `difference`.
+-- | An alias for 'difference'.
 (\\) :: SetContainer a => a -> a -> a
 (\\) = difference
 {-# INLINE (\\) #-}
 
--- | An alias for `intersection`.
+-- | An alias for 'intersection'.
 intersect :: SetContainer a => a -> a -> a
 intersect = intersection
 {-# INLINE intersect #-}
@@ -413,14 +415,14 @@
 sortWith :: (Ord a, IsSequence c) => (Element c -> a) -> c -> c
 sortWith f = sortBy $ comparing f
 
--- | We define our own @undefined@ which is marked as deprecated. This makes it
+-- | We define our own 'undefined' which is marked as deprecated. This makes it
 -- useful to use during development, but let's you more easily getting
 -- notification if you accidentally ship partial code in production.
 --
 -- The classy prelude recommendation for when you need to really have a partial
--- function in production is to use @error@ with a very descriptive message so
+-- function in production is to use 'error' with a very descriptive message so
 -- that, in case an exception is thrown, you get more information than
--- @Prelude.undefined@.
+-- @"Prelude".'Prelude.undefined'@.
 --
 -- Since 0.5.5
 undefined :: a
@@ -457,9 +459,9 @@
 fpFromString :: String -> FilePath
 fpFromString = F.decodeString
 
--- | Translates a FilePath to a Text
--- Warns if there are non-unicode
--- sequences in the file name
+-- | Translates a 'FilePath' to a 'Text'
+--
+-- Warns if there are non-unicode sequences in the file name
 fpToTextWarn :: MonadIO m => FilePath -> m Text
 fpToTextWarn fp = case F.toText fp of
     Right ok -> return ok
@@ -467,23 +469,24 @@
         putStrLn $ pack $ "non-unicode filepath: " ++ F.encodeString fp
         return bad
 
--- | Translates a FilePath to a Text
+-- | Translates a 'FilePath' to a 'Text'
+--
 -- Throws an exception if there are non-unicode
 -- sequences in the file name
 --
 -- Use this to assert that you know
--- a filename will translate properly into a Text
+-- a filename will translate properly into a 'Text'.
 -- If you created the filename, this should be the case.
 fpToTextEx :: FilePath -> Text
 fpToTextEx fp = either (const $ error errorMsg) id $ F.toText fp
   where
     errorMsg = "fpToTextEx: non-unicode filepath: " ++ F.encodeString fp
 
--- | Translates a FilePath to a Text
+-- | Translates a 'FilePath' to a 'Text'
 -- This translation is not correct for a (unix) filename
--- which can contain arbitrary (non-unicode) bytes: those bytes will be discarded
+-- which can contain arbitrary (non-unicode) bytes: those bytes will be discarded.
 --
--- This means you cannot translate the Text back to the original file name.
+-- This means you cannot translate the 'Text' back to the original file name.
 --
 -- If you control or otherwise understand the filenames
 -- and believe them to be unicode valid consider using 'fpToTextEx' or 'fpToTextWarn'
@@ -498,8 +501,9 @@
 -- Should eventually exist in mono-foldable and be extended to MonoFoldable
 -- when doing that should re-run the haskell-ordnub benchmarks
 
--- | same behavior as nub, but requires Hashable & Eq and is O(n log n)
--- https://github.com/nh2/haskell-ordnub
+-- | same behavior as 'Data.List.nub', but requires 'Hashable' & 'Eq' and is @O(n log n)@
+--
+-- <https://github.com/nh2/haskell-ordnub>
 hashNub :: (Hashable a, Eq a) => [a] -> [a]
 hashNub = go HashSet.empty
   where
@@ -507,8 +511,9 @@
     go s (x:xs) | x `HashSet.member` s = go s xs
                 | otherwise            = x : go (HashSet.insert x s) xs
 
--- | same behavior as nub, but requires Ord and is O(n log n)
--- https://github.com/nh2/haskell-ordnub
+-- | same behavior as 'Data.List.nub', but requires 'Ord' and is @O(n log n)@
+--
+-- <https://github.com/nh2/haskell-ordnub>
 ordNub :: (Ord a) => [a] -> [a]
 ordNub = go Set.empty
   where
@@ -516,8 +521,9 @@
     go s (x:xs) | x `Set.member` s = go s xs
                 | otherwise        = x : go (Set.insert x s) xs
 
--- | same behavior as nubBy, but requires Ord and is O(n log n)
--- https://github.com/nh2/haskell-ordnub
+-- | same behavior as 'Data.List.nubBy', but requires 'Ord' and is @O(n log n)@
+--
+-- <https://github.com/nh2/haskell-ordnub>
 ordNubBy :: (Ord b) => (a -> b) -> (a -> a -> Bool) -> [a] -> [a]
 ordNubBy p f = go Map.empty
   -- When removing duplicates, the first function assigns the input to a bucket,
@@ -564,13 +570,13 @@
 checkSTM = STM.check
 {-# INLINE checkSTM #-}
 
--- | Only perform the action if the predicate returns @True@.
+-- | Only perform the action if the predicate returns 'True'.
 --
 -- Since 0.9.2
 whenM :: Monad m => m Bool -> m () -> m ()
 whenM mbool action = mbool >>= flip when action
 
--- | Only perform the action if the predicate returns @False@.
+-- | Only perform the action if the predicate returns 'False'.
 --
 -- Since 0.9.2
 unlessM :: Monad m => m Bool -> m () -> m ()
diff --git a/classy-prelude.cabal b/classy-prelude.cabal
--- a/classy-prelude.cabal
+++ b/classy-prelude.cabal
@@ -1,5 +1,5 @@
 name:                classy-prelude
-version:             0.10.4
+version:             0.10.5
 synopsis:            A typeclass-based Prelude.
 description:         Modern best practices without name collisions. No partial functions are exposed, but modern data structures are, without requiring import lists. Qualified modules also are not needed: instead operations are based on type-classes from the mono-traversable package.
 
@@ -39,6 +39,7 @@
                      , primitive
                      , mtl
                      , bifunctors
+                     , mutable-containers >= 0.2 && < 0.3
   ghc-options:         -Wall -fno-warn-orphans
 
 test-suite test
