diff --git a/CHANGELOG.md b/CHANGELOG.md
new file mode 100644
--- /dev/null
+++ b/CHANGELOG.md
@@ -0,0 +1,63 @@
+# 1.6
+
+* Restrict to min GHC 8.6
+* Add Contravariant
+* Add OverloadedLabels and Records
+* Add STM.orElse
+
+# 1.5
+
+* Exclude Data.Semigroup.Option
+* Restrict to min GHC 8.4
+* Add focused preludes for data types and operators
+
+# 1.4
+
+* Restrict to min GHC 8.0 and give preference to MonadFail
+* Add IsList, Generic1 and export all of System.IO
+
+# 1.3
+
+* Give preference to Semigroup definitions over Monoid
+
+# 1.2
+
+* Replace the `Foreign` export with `Foreign.Storable`, `Foreign.Ptr`, `Foreign.ForeignPtr`, `Foreign.StablePtr`. It's more conservative and way less likely to cause name collisions.
+
+# 1.1
+
+* Export `Foreign`
+
+# 1.0.1
+
+* Relaxed the "base" dependency
+
+# 1
+
+No changes.
+
+# 0.2
+
+* Reexported `Data.Bifunctor`.
+
+* `first` and `second` are now (conditionally) exported from `Data.Bifunctor`, not `Control.Arrow`; note that if your version of base is lower than 4.8, `first` and `second` won't be available at all.
+
+# 0.1.21
+
+* Reexported `printf` and `hPrintf` from `Text.Printf`.
+
+# 0.1.20
+
+* Reexported `Numeric`.
+
+# 0.1.19
+
+* Avoided the clash between `(&)` and `sortOn` defined in the package and versions of these functions imported from base.
+
+# 0.1.18
+
+* Added implementations of `(&)` and `sortOn` (normally not available in older versions of base).
+
+# 0.1.17
+
+* Reexported `Control.Monad.Fix`.
diff --git a/Setup.hs b/Setup.hs
deleted file mode 100644
--- a/Setup.hs
+++ /dev/null
@@ -1,2 +0,0 @@
-import Distribution.Simple
-main = defaultMain
diff --git a/base-prelude.cabal b/base-prelude.cabal
--- a/base-prelude.cabal
+++ b/base-prelude.cabal
@@ -1,52 +1,42 @@
-name:
-  base-prelude
-version:
-  0.1.21
-synopsis:
-  The most complete prelude formed from only the "base" package
+cabal-version:      3.0
+name:               base-prelude
+version:            1.6.1.1
+synopsis:           Featureful preludes formed solely from the "base" package
 description:
-  A library which reexports all non-conflicting and
+  A library which aims to reexport all the non-conflicting and
   most general definitions from the \"base\" package.
   This includes APIs for applicatives, arrows, monoids, foldables, traversables,
   exceptions, generics, ST, MVars and STM.
-  .
   This package will never have any dependencies other than \"base\".
-category:
-  Prelude
-homepage:
-  https://github.com/nikita-volkov/base-prelude 
-bug-reports:
-  https://github.com/nikita-volkov/base-prelude/issues 
-author:
-  Nikita Volkov <nikita.y.volkov@mail.ru>
-maintainer:
-  Nikita Volkov <nikita.y.volkov@mail.ru>
-copyright:
-  (c) 2014, Nikita Volkov
-license:
-  MIT
-license-file:
-  LICENSE
-build-type:
-  Simple
-cabal-version:
-  >=1.10
+  Besides a rich prelude it provides limited ones like "BasePrelude.DataTypes",
+  which only exports the data-types defined across the \"base\" package,
+  and "BasePrelude.Operators", which only exports the common operators.
+  /Versioning policy/
+  The versioning policy of this package deviates from PVP in the sense
+  that its exports in part are transitively determined by the version of \"base\".
+  Therefore it's recommended for the users of \"base-prelude\" to specify
+  the bounds of \"base\" as well.
 
+category:           Prelude
+homepage:           https://github.com/nikita-volkov/base-prelude
+bug-reports:        https://github.com/nikita-volkov/base-prelude/issues
+author:             Nikita Volkov <nikita.y.volkov@mail.ru>
+maintainer:         Nikita Volkov <nikita.y.volkov@mail.ru>
+copyright:          (c) 2014, Nikita Volkov
+license:            MIT
+license-file:       LICENSE
+extra-source-files: CHANGELOG.md
 
 source-repository head
-  type:
-    git
-  location:
-    git://github.com/nikita-volkov/base-prelude.git
-
+  type:     git
+  location: git://github.com/nikita-volkov/base-prelude.git
 
 library
-  hs-source-dirs:
-    library
-  other-modules:
+  hs-source-dirs:   library
+  default-language: Haskell2010
   exposed-modules:
     BasePrelude
-  build-depends:
-    base >= 4.6 && < 4.9
-  default-language:
-    Haskell2010
+    BasePrelude.DataTypes
+    BasePrelude.Operators
+
+  build-depends:    base >=4.12 && <5
diff --git a/library/BasePrelude.hs b/library/BasePrelude.hs
--- a/library/BasePrelude.hs
+++ b/library/BasePrelude.hs
@@ -1,175 +1,85 @@
+{-# OPTIONS_GHC -Wno-dodgy-imports -Wno-unused-imports #-}
+
 -- |
--- This module reexports most of the definitions from the \"base\" package,
--- which are meant to be imported unqualified.
+-- Reexports of most of the definitions from the \"base\" package,
+-- which it is a common practice to import unqualified.
 --
 -- For details check out the source.
 module BasePrelude
-(
-  module Exports,
-  -- * Reimplementations of functions presented in versions of \"base\" newer than 4.6
-  -- ** Data.Bool
-  bool,
-  -- ** Data.Function
-  (&),
-  -- ** Data.Functor
-  ($>),
-  -- ** Data.List
-  isSubsequenceOf,
-  sortOn,
-  uncons,
-  -- ** Debug.Trace
-  traceShowId,
-  traceM,
-  traceShowM,
-)
+  ( module Exports,
+  )
 where
 
--- Reexports
--------------------------
-
 import Control.Applicative as Exports
-import Control.Arrow as Exports
+import Control.Arrow as Exports hiding (first, second)
 import Control.Category as Exports
 import Control.Concurrent as Exports
 import Control.Exception as Exports
-import Control.Monad as Exports hiding (mapM_, sequence_, forM_, msum, mapM, sequence, forM)
+import Control.Monad as Exports hiding (fail, forM, forM_, mapM, mapM_, msum, sequence, sequence_)
+import Control.Monad.Fail as Exports
 import Control.Monad.Fix as Exports hiding (fix)
+import Control.Monad.IO.Class as Exports
 import Control.Monad.ST as Exports
+import Data.Bifunctor as Exports
 import Data.Bits as Exports
-import Data.Bool as Exports hiding (bool)
+import Data.Bool as Exports
 import Data.Char as Exports
+import Data.Coerce as Exports
 import Data.Complex as Exports
 import Data.Data as Exports
 import Data.Dynamic as Exports
 import Data.Either as Exports
 import Data.Fixed as Exports
-import Data.Foldable as Exports
-import Data.Functor as Exports hiding (($>))
-import Data.Function as Exports hiding ((.), id, (&))
-import Data.Int as Exports
+import Data.Foldable as Exports hiding (toList)
+import Data.Function as Exports hiding (id, (.))
+import Data.Functor as Exports hiding (unzip)
+import Data.Functor.Classes as Exports
+import Data.Functor.Compose as Exports
+import Data.Functor.Contravariant as Exports
+import Data.Functor.Identity as Exports
 import Data.IORef as Exports
+import Data.Int as Exports
 import Data.Ix as Exports
-import Data.List as Exports hiding (sortOn, isSubsequenceOf, uncons, concat, foldr, foldl1, maximum, minimum, product, sum, all, and, any, concatMap, elem, foldl, foldr1, notElem, or, find, maximumBy, minimumBy, mapAccumL, mapAccumR, foldl')
+import Data.List as Exports hiding (all, and, any, concat, concatMap, elem, find, foldl, foldl', foldl1, foldr, foldr1, mapAccumL, mapAccumR, maximum, maximumBy, minimum, minimumBy, notElem, or, product, sum)
+import Data.List.NonEmpty as Exports (NonEmpty (..))
 import Data.Maybe as Exports
-import Data.Monoid as Exports
+import Data.Monoid as Exports hiding (First (..), Last (..), (<>))
 import Data.Ord as Exports
+import Data.Proxy as Exports
 import Data.Ratio as Exports
 import Data.STRef as Exports
+import Data.Semigroup as Exports hiding (Option)
 import Data.String as Exports
 import Data.Traversable as Exports
 import Data.Tuple as Exports
 import Data.Unique as Exports
 import Data.Version as Exports
+import Data.Void as Exports
 import Data.Word as Exports
-import Debug.Trace as Exports hiding (traceShowId, traceM, traceShowM)
-import Foreign.Storable as Exports (Storable)
-import GHC.Conc as Exports hiding (withMVar, threadWaitWriteSTM, threadWaitWrite, threadWaitReadSTM, threadWaitRead)
-import GHC.Exts as Exports (lazy, inline, sortWith, groupWith)
-import GHC.Generics as Exports (Generic)
+import Debug.Trace as Exports
+import Foreign.ForeignPtr as Exports
+import Foreign.Ptr as Exports
+import Foreign.StablePtr as Exports
+import Foreign.Storable as Exports
+import GHC.Conc as Exports hiding (orElse, threadWaitRead, threadWaitReadSTM, threadWaitWrite, threadWaitWriteSTM, withMVar)
+import GHC.Exts as Exports (IsList (..), groupWith, inline, lazy, sortWith)
+import GHC.Generics as Exports (Generic, Generic1)
 import GHC.IO.Exception as Exports
+import GHC.OverloadedLabels as Exports
+import GHC.Records as Exports
 import Numeric as Exports
-import Prelude as Exports hiding (concat, foldr, mapM_, sequence_, foldl1, maximum, minimum, product, sum, all, and, any, concatMap, elem, foldl, foldr1, notElem, or, mapM, sequence, id, (.))
+import Numeric.Natural as Exports
 import System.Environment as Exports
 import System.Exit as Exports
-import System.IO as Exports (Handle, hClose)
+import System.IO as Exports
 import System.IO.Error as Exports
 import System.IO.Unsafe as Exports
 import System.Mem as Exports
 import System.Mem.StableName as Exports
 import System.Timeout as Exports
 import Text.ParserCombinators.ReadP as Exports (ReadP, ReadS, readP_to_S, readS_to_P)
-import Text.ParserCombinators.ReadPrec as Exports (ReadPrec, readPrec_to_P, readP_to_Prec, readPrec_to_S, readS_to_Prec)
-import Text.Printf as Exports (printf, hPrintf)
-import Text.Read as Exports (Read(..), readMaybe, readEither)
+import Text.ParserCombinators.ReadPrec as Exports (ReadPrec, readP_to_Prec, readPrec_to_P, readPrec_to_S, readS_to_Prec)
+import Text.Printf as Exports (hPrintf, printf)
+import Text.Read as Exports (Read (..), readEither, readMaybe)
 import Unsafe.Coerce as Exports
-
-
--- Reimplementations
--------------------------
-
--- | Case analysis for the 'Bool' type.
--- @bool a b p@ evaluates to @a@ when @p@ is @False@, and evaluates to @b@
--- when @p@ is @True@.
-bool :: a -> a -> Bool -> a
-bool f t b = if b then t else f
-
-{-|
-Like 'traceShow' but returns the shown value instead of a third value.
--}
-traceShowId :: (Show a) => a -> a
-traceShowId a = trace (show a) a
-
-{-|
-Like 'trace' but returning unit in an arbitrary monad. Allows for convenient
-use in do-notation. Note that the application of 'trace' is not an action in the
-monad, as 'traceIO' is in the 'IO' monad.
-
-> ... = do
->   x <- ...
->   traceM $ "x: " ++ show x
->   y <- ...
->   traceM $ "y: " ++ show y
--}
-traceM :: (Monad m) => String -> m ()
-traceM string = trace string $ return ()
-
-{-|
-Like 'traceM', but uses 'show' on the argument to convert it to a 'String'.
-
-> ... = do
->   x <- ...
->   traceShowM $ x
->   y <- ...
->   traceShowM $ x + y
--}
-traceShowM :: (Show a, Monad m) => a -> m ()
-traceShowM = traceM . show
-
-infixl 4 $>
-
--- | Flipped version of '<$'.
-($>) :: Functor f => f a -> b -> f b
-($>) = flip (<$)
-
-infixl 1 &
-
--- | '&' is a reverse application operator.  This provides notational
--- convenience.  Its precedence is one higher than that of the forward
--- application operator '$', which allows '&' to be nested in '$'.
-(&) :: a -> (a -> b) -> b
-x & f = f x
-
--- | The 'isSubsequenceOf' function takes two lists and returns 'True' if the
--- first list is a subsequence of the second list.
---
--- @'isSubsequenceOf' x y@ is equivalent to @'elem' x ('subsequences' y)@.
---
--- ==== __Examples__
---
--- >>> isSubsequenceOf "GHC" "The Glorious Haskell Compiler"
--- True
--- >>> isSubsequenceOf ['a','d'..'z'] ['a'..'z']
--- True
--- >>> isSubsequenceOf [1..10] [10,9..0]
--- False
-isSubsequenceOf :: (Eq a) => [a] -> [a] -> Bool
-isSubsequenceOf []    _                    = True
-isSubsequenceOf _     []                   = False
-isSubsequenceOf a@(x:a') (y:b) | x == y    = isSubsequenceOf a' b
-                               | otherwise = isSubsequenceOf a b
-
--- | Decompose a list into its head and tail. If the list is empty,
--- returns 'Nothing'. If the list is non-empty, returns @'Just' (x, xs)@,
--- where @x@ is the head of the list and @xs@ its tail.
-uncons        :: [a] -> Maybe (a, [a])
-uncons []     = Nothing
-uncons (x:xs) = Just (x, xs)
-
--- | Sort a list by comparing the results of a key function applied to each
--- element.  @sortOn f@ is equivalent to @sortBy . comparing f@, but has the
--- performance advantage of only evaluating @f@ once for each element in the
--- input list.  This is called the decorate-sort-undecorate paradigm, or
--- Schwartzian transform.
-sortOn :: Ord b => (a -> b) -> [a] -> [a]
-sortOn f =
-  map snd . sortBy (comparing fst) . map (\x -> let y = f x in y `seq` (y, x))
+import Prelude as Exports hiding (all, and, any, concat, concatMap, elem, fail, foldl, foldl1, foldr, foldr1, id, mapM, mapM_, maximum, minimum, notElem, or, product, sequence, sequence_, sum, (.))
diff --git a/library/BasePrelude/DataTypes.hs b/library/BasePrelude/DataTypes.hs
new file mode 100644
--- /dev/null
+++ b/library/BasePrelude/DataTypes.hs
@@ -0,0 +1,55 @@
+-- |
+-- A module that reexports only the data types
+-- defined across various modules of the \"base\" package.
+--
+-- By data types we mean that it is the ones we use
+-- to define data structures.
+-- It is not abstraction integration wrappers,
+-- like 'Data.Semigroup.First'.
+-- It is not resource types like 'System.IO.Handle'.
+module BasePrelude.DataTypes
+  ( -- * From "Prelude"
+    Prelude.Bool (..),
+    Prelude.Char,
+    Prelude.Double,
+    Prelude.Either (..),
+    Prelude.Float,
+    Prelude.Integer,
+    Prelude.Maybe (..),
+    Prelude.String,
+
+    -- * From "Data.Int"
+    Data.Int.Int,
+    Data.Int.Int8,
+    Data.Int.Int16,
+    Data.Int.Int32,
+    Data.Int.Int64,
+
+    -- * From "Data.Word"
+    Data.Word.Word,
+    Data.Word.Word8,
+    Data.Word.Word16,
+    Data.Word.Word32,
+    Data.Word.Word64,
+
+    -- * From "Data.Complex"
+    Data.Complex.Complex (..),
+
+    -- * From "Data.Ratio"
+    Data.Ratio.Rational,
+
+    -- * From "Numeric.Natural"
+    Numeric.Natural.Natural,
+
+    -- * From "Data.List.NonEmpty"
+    Data.List.NonEmpty.NonEmpty (..),
+  )
+where
+
+import qualified Data.Complex
+import qualified Data.Int
+import qualified Data.List.NonEmpty
+import qualified Data.Ratio
+import qualified Data.Word
+import qualified Numeric.Natural
+import qualified Prelude
diff --git a/library/BasePrelude/Operators.hs b/library/BasePrelude/Operators.hs
new file mode 100644
--- /dev/null
+++ b/library/BasePrelude/Operators.hs
@@ -0,0 +1,80 @@
+-- |
+-- A collection of common operators provided across
+-- various modules of the \"base\" package.
+module BasePrelude.Operators
+  ( -- * From "Control.Applicative"
+    (Control.Applicative.*>),
+    (Control.Applicative.<*),
+    (Control.Applicative.<*>),
+    (Control.Applicative.<**>),
+    (Control.Applicative.<|>),
+
+    -- * From "Control.Monad"
+    (Control.Monad.<=<),
+    (Control.Monad.=<<),
+    (Control.Monad.>=>),
+    (Control.Monad.>>),
+    (Control.Monad.>>=),
+
+    -- * From "Data.Bits"
+    (Data.Bits..&.),
+    (Data.Bits..|.),
+
+    -- * From "Data.Bool"
+    (Data.Bool.&&),
+    (Data.Bool.||),
+    (Data.Eq./=),
+    (Data.Eq.==),
+
+    -- * From "Data.Function"
+    (Data.Function.$),
+    (Data.Function.&),
+    (Data.Function..),
+
+    -- * From "Data.Functor"
+    (Data.Functor.$>),
+    (Data.Functor.<$),
+    (Data.Functor.<$>),
+    (Data.Functor.<&>),
+
+    -- * From "Data.Functor.Contravariant"
+    (Data.Functor.Contravariant.>$),
+    (Data.Functor.Contravariant.>$<),
+    (Data.Functor.Contravariant.>$$<),
+    (Data.Functor.Contravariant.$<),
+
+    -- * From "Data.Ord"
+    (Data.Ord.<),
+    (Data.Ord.<=),
+    (Data.Ord.>),
+    (Data.Ord.>=),
+
+    -- * From "Data.Ratio"
+    (Data.Ratio.%),
+
+    -- * From "Data.Semigroup"
+    (Data.Semigroup.<>),
+
+    -- * From "Prelude"
+    (Prelude.$!),
+    (Prelude.*),
+    (Prelude.+),
+    (Prelude.-),
+    (Prelude./),
+    (Prelude.^),
+    (Prelude.^^),
+  )
+where
+
+import qualified Control.Applicative
+import qualified Control.Monad
+import qualified Data.Bits
+import qualified Data.Bool
+import qualified Data.Eq
+import qualified Data.Function
+import qualified Data.Functor
+import qualified Data.Functor.Contravariant
+import qualified Data.Ord
+import qualified Data.Ratio
+import qualified Data.Semigroup
+import qualified Prelude
