diff --git a/CHANGES.md b/CHANGES.md
--- a/CHANGES.md
+++ b/CHANGES.md
@@ -1,8 +1,17 @@
+1.8.2
+=====
+
+* [#289](https://github.com/serokell/universum/pull/289):
+  Make universum work with LTS-21.0.
+  * Re-export `(~)` type operator.
+* [#283](https://github.com/serokell/universum/pull/283):
+  Bump the upper version bound on `text` to `2.0.2`.
+
 1.8.1.1
 =======
 
 * [#282](https://github.com/serokell/universum/pull/282):
-  Bump version bound on `text` to `2.0.1`.
+  Bump the upper version bound on `text` to `2.0.1`.
 
 1.8.1
 =====
diff --git a/README.md b/README.md
--- a/README.md
+++ b/README.md
@@ -3,8 +3,9 @@
 
 [![GitHub CI](https://github.com/serokell/universum/workflows/CI/badge.svg)](https://github.com/serokell/universum/actions)
 [![Hackage](https://img.shields.io/hackage/v/universum.svg)](https://hackage.haskell.org/package/universum)
-[![Stackage LTS](http://stackage.org/package/universum/badge/lts)](http://stackage.org/lts/package/universum)
-[![Stackage Nightly](http://stackage.org/package/universum/badge/nightly)](http://stackage.org/nightly/package/universum)
+<!-- TODO [#288]: enable these once -->
+<!-- [![Stackage LTS](http://stackage.org/package/universum/badge/lts)](http://stackage.org/lts/package/universum) -->
+<!-- [![Stackage Nightly](http://stackage.org/package/universum/badge/nightly)](http://stackage.org/nightly/package/universum) -->
 [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
 
 `universum` is a custom prelude used in @Serokell that has:
diff --git a/src/Universum/Base.hs b/src/Universum/Base.hs
--- a/src/Universum/Base.hs
+++ b/src/Universum/Base.hs
@@ -1,3 +1,4 @@
+{-# LANGUAGE CPP          #-}
 {-# LANGUAGE BangPatterns #-}
 {-# LANGUAGE Unsafe       #-}
 
@@ -24,6 +25,9 @@
        , module Data.Proxy
        , module Data.Typeable
        , module Data.Void
+#if MIN_VERSION_base(4,17,0)
+       , module Data.Type.Equality
+#endif
 
        , module GHC.Base
        , module GHC.Enum
@@ -67,6 +71,9 @@
 import Data.Proxy (Proxy (..))
 import Data.Typeable (Typeable)
 import Data.Void (Void, absurd, vacuous)
+#if MIN_VERSION_base(4,17,0)
+import Data.Type.Equality (type (~))
+#endif
 
 import GHC.Base (String, asTypeOf, maxInt, minInt, ord, seq)
 import GHC.Enum (Bounded (..), Enum (..), boundedEnumFrom, boundedEnumFromThen)
diff --git a/src/Universum/Container/Class.hs b/src/Universum/Container/Class.hs
--- a/src/Universum/Container/Class.hs
+++ b/src/Universum/Container/Class.hs
@@ -231,9 +231,13 @@
 
 instance FromList IntSet
 instance Ord a => FromList (Set a)
-instance (Eq k, Hashable k) => FromList (HashMap k v)
 instance FromList (IntMap v)
 instance Ord k => FromList (Map k v)
+#if MIN_VERSION_hashable(1,4,0)
+instance (Hashable k) => FromList (HashMap k v)
+#else
+instance (Eq k, Hashable k) => FromList (HashMap k v)
+#endif
 
 instance FromList T.Text
 instance FromList TL.Text
@@ -575,7 +579,11 @@
     notElem = Set.notMember
     {-# INLINE notElem #-}
 
+#if MIN_VERSION_hashable(1,4,0)
+instance (Hashable v) => Container (HashSet v) where
+#else
 instance (Eq v, Hashable v) => Container (HashSet v) where
+#endif
     elem = HashSet.member
     {-# INLINE elem #-}
 
diff --git a/src/Universum/Monad/Container.hs b/src/Universum/Monad/Container.hs
--- a/src/Universum/Monad/Container.hs
+++ b/src/Universum/Monad/Container.hs
@@ -1,3 +1,4 @@
+{-# LANGUAGE CPP          #-}
 {-# LANGUAGE Trustworthy  #-}
 {-# LANGUAGE TypeFamilies #-}
 
@@ -18,6 +19,9 @@
 import Data.Function ((.))
 import Data.Traversable (Traversable (traverse))
 import Prelude (Bool (..), Monoid, flip)
+#if MIN_VERSION_base(4,17,0)
+import Data.Type.Equality (type (~))
+#endif
 
 import Universum.Base (IO)
 import Universum.Container (Container, Element, fold, toList)
diff --git a/src/Universum/String/Conversion.hs b/src/Universum/String/Conversion.hs
--- a/src/Universum/String/Conversion.hs
+++ b/src/Universum/String/Conversion.hs
@@ -34,7 +34,10 @@
 import Data.Maybe (Maybe)
 import Data.String (String)
 import qualified Data.Text.Internal as T
+
+#if !MIN_VERSION_text(2,0,2)
 import qualified Data.Text.Internal.Fusion.Common as TF
+#endif
 
 import Universum.Functor ((<$>))
 import Universum.String.Reexport (ByteString, IsString, Read, Text, fromString)
@@ -164,6 +167,26 @@
 instance ToString LT.Text where
     toString = LT.unpack
 
+{- [Note toString-toText-rewritting]
+
+Note ON MAINTENANCE of rewrite rules below.
+
+Whenever you want to allow a newer version of @text@ package, check:
+* The @text conversions@ benchmark, that the numbers with and without the rules
+are still the expected ones (see the comments there for what to expect).
+* You may optionally check whether any changes to `pack` and `unpack` functions
+and their `INLINE`/`NOINLINE` annotations took place.
+The current rewrite rules match with what happens in `text` package
+at the e5644b663c32c01a1de7299a5e711216755e01bc commit, and next time
+you can just check `git diff <that commit>..HEAD`.
+
+If these points hold, it should be safe to raise the upper bound on `text` version.
+
+If not, first do the necessary changes (preserving the backward compatibility),
+update the commit id above if you checked the code of the `text` package.
+Then bump the version constraint.
+-}
+
 {-
 
 @toString . toText@ pattern may occur quite often after inlining because
@@ -171,34 +194,22 @@
 there are still some libraries which use 'String's and thus make us perform
 conversions back and forth.
 
-Note that @toString . toText@ is not strictly equal to identity function, see
-explanation in the comment below.
+Note that, as documentation for 'T.pack' function mentions, @toString . toText@
+is not strictly equal to the identity function. Thus, replacing @toString . toText@
+with @id@ will result in losing transformation of surrogate code points.
+But in the most cases this is what the user wants.
 -}
 
 {-# RULES "pack/unpack" [~0]
     forall s. T.unpack (T.pack s) = s
 #-}
 
-{- [Note toString-toText-rewritting]
+#if !MIN_VERSION_text(2,0,2)
+{-
 
 We can do even better than above if take rules defined in 'Data.Text' into
 account.
 
-Note ON MAINTENANCE: whenever you need to update the used version of @text@ package,
-you have to check whether the comment below is still valid.
-However, you can cut down by looking at the diff between versions of @text@, and
-seeing if implementation of any of these functions have changed:
-  * pack
-  * unpack
-  * streamList
-  * unstreamList
-  * safe
-  * any RULES definition (if some is added, this counts)
-Also check the @text conversions@ benchmark, that the numbers with and without
-the rules are still the expected ones
-If none of mentioned have changed, then it is safe to assume that everything
-is still fine.
-
 Quoting investigation of @int-index:
 
 If we look at @unpack@ and @pack@ they are defined as
@@ -269,6 +280,7 @@
 {-# RULES "pack/unpack internal" [1]
     forall s. TF.unstreamList (TF.map T.safe (TF.streamList s)) = s
 #-}
+#endif
 
 {- In case if GHC didn't manage to inline and rewrite everything in
 the remaining phases (@Data.Text.pack@ is inlined at 1-st phase),
diff --git a/src/Universum/VarArg.hs b/src/Universum/VarArg.hs
--- a/src/Universum/VarArg.hs
+++ b/src/Universum/VarArg.hs
@@ -1,9 +1,11 @@
+{-# LANGUAGE CPP                    #-}
 {-# LANGUAGE FlexibleContexts       #-}
 {-# LANGUAGE FlexibleInstances      #-}
 {-# LANGUAGE FunctionalDependencies #-}
 {-# LANGUAGE MultiParamTypeClasses  #-}
 {-# LANGUAGE Safe                   #-}
 {-# LANGUAGE TypeFamilies           #-}
+{-# LANGUAGE TypeOperators          #-}
 {-# LANGUAGE UndecidableInstances   #-}
 
 -- | Provides operator of variable-arguments function composition.
@@ -11,6 +13,10 @@
 module Universum.VarArg
        ( SuperComposition(..)
        ) where
+
+#if MIN_VERSION_base(4,17,0)
+import Data.Type.Equality (type (~))
+#endif
 
 -- $setup
 -- >>> import Universum.Base ((+))
diff --git a/test/Test/Universum/StringProps.hs b/test/Test/Universum/StringProps.hs
--- a/test/Test/Universum/StringProps.hs
+++ b/test/Test/Universum/StringProps.hs
@@ -28,9 +28,7 @@
   str <- forAll unicodeAllString
   toString (toText str) === str
 
--- | See comment to this function:
--- <http://hackage.haskell.org/package/text-1.2.3.1/docs/src/Data.Text.Internal.html#safe>
---
+-- |
 -- While 'String' may contain surrogate UTF-16 code points, actually UTF-8
 -- doesn't allow them, as well as 'Text'. 'Data.Text.pack' replaces invalid
 -- characters with unicode replacement character, so by default
@@ -41,7 +39,8 @@
 hprop_StringToTextAndBackSurrogate :: Property
 hprop_StringToTextAndBackSurrogate = property $ do
   -- Surrogate character like this one should remain intact
-  -- Without rewrite rule this string would be transformed to "\9435"
+  -- Without the rewrite rule this string would be transformed to some other,
+  -- valid string
   let str = "\xD800"
   toString (toText str) === str
 
diff --git a/universum.cabal b/universum.cabal
--- a/universum.cabal
+++ b/universum.cabal
@@ -1,6 +1,6 @@
 cabal-version:       2.2
 name:                universum
-version:             1.8.1.1
+version:             1.8.2
 synopsis:            Custom prelude used in Serokell
 description:         See README.md file for more details.
 homepage:            https://github.com/serokell/universum
@@ -13,11 +13,11 @@
 stability:           stable
 build-type:          Simple
 bug-reports:         https://github.com/serokell/universum/issues
-tested-with:         GHC == 8.6.5
-                   , GHC == 8.8.4
+tested-with:         GHC == 8.8.4
                    , GHC == 8.10.7
-                   , GHC == 9.0.1
-                   , GHC == 9.2.2
+                   , GHC == 9.0.2
+                   , GHC == 9.2.8
+                   , GHC == 9.4.5
 extra-doc-files:     CHANGES.md
                    , CONTRIBUTING.md
                    , README.md
@@ -48,6 +48,8 @@
 
   default-language:    Haskell2010
 
+  default-extensions:  TypeOperators
+
 library
   import:              common-options
   hs-source-dirs:      src
@@ -105,7 +107,7 @@
                      , stm
                      -- Make sure that "toString-toText-rewritting" note
                      -- is still valid when bumping this constraint.
-                     , text >= 1.0.0.0 && <= 2.0.1
+                     , text >= 1.0.0.0 && <= 2.0.2
                      , transformers
                      , unordered-containers
                      , utf8-string
