diff --git a/CHANGELOG.md b/CHANGELOG.md
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,13 @@
+## [v1.4.4](https://github.com/diagrams/diagrams-lib/tree/v1.4.4) (2021-05-24)
+
+- Bumps to upper bounds, to allow building with:
+    - `base-4.15` (tested with GHC 9.0.1)
+    - `optparse-applicative` (tested with GHC 8.8.4 & 8.10.2)
+
+- Updated use of Kinds thoughout the package
+
+- Drop support for GHC 8.2 or earlier
+
 ## [v1.4.3](https://github.com/diagrams/diagrams-lib/tree/v1.4.3) (2019-11-06)
 
 - Bumps to upper bounds, to allow building with:
diff --git a/diagrams-lib.cabal b/diagrams-lib.cabal
--- a/diagrams-lib.cabal
+++ b/diagrams-lib.cabal
@@ -1,5 +1,5 @@
 Name:                diagrams-lib
-Version:             1.4.3
+Version:             1.4.4
 Synopsis:            Embedded domain-specific language for declarative graphics
 Description:         Diagrams is a flexible, extensible EDSL for creating
                      graphics of many types.  Graphics can be created
@@ -21,7 +21,7 @@
 Cabal-version:       1.18
 Extra-source-files:  CHANGELOG.md, README.markdown, diagrams/*.svg
 Extra-doc-files:     diagrams/*.svg
-Tested-with:         GHC ==7.10.3 || ==8.0.2 || ==8.2.2 || ==8.4.3 || ==8.6.5 || ==8.8.1
+Tested-with:         GHC ==8.4.4 || ==8.6.5 || ==8.8.4 || ==8.10.4 || ==9.0.1
 Source-repository head
   type:     git
   location: http://github.com/diagrams/diagrams-lib.git
@@ -100,26 +100,26 @@
                        Diagrams.TwoD.Types,
                        Diagrams.TwoD.Vector,
                        Diagrams.Util
-  Build-depends:       base >= 4.8 && < 4.14,
+  Build-depends:       base >= 4.9 && < 4.16,
                        containers >= 0.3 && < 0.7,
                        array >= 0.3 && < 0.6,
                        semigroups >= 0.3.4 && < 0.20,
-                       monoid-extras >= 0.3 && < 0.6,
+                       monoid-extras >= 0.6 && < 0.7,
                        dual-tree >= 0.2 && < 0.3,
-                       diagrams-core >= 1.4 && < 1.5,
+                       diagrams-core >= 1.4 && < 1.6,
                        diagrams-solve >= 0.1 && < 0.2,
                        active >= 0.2 && < 0.3,
                        colour >= 2.3.2 && < 2.4,
                        data-default-class < 0.2,
                        fingertree >= 0.1 && < 0.2,
                        intervals >= 0.7 && < 0.10,
-                       lens >= 4.6 && < 4.19,
+                       lens >= 4.6 && < 5.1,
                        tagged >= 0.7,
-                       optparse-applicative >= 0.11 && < 0.16,
+                       optparse-applicative >= 0.11 && < 0.17,
                        filepath,
                        JuicyPixels >= 3.3.4 && < 3.4,
                        hashable >= 1.1 && < 1.4,
-                       linear >= 1.20.1 && < 1.21,
+                       linear >= 1.20.1 && < 1.22,
                        adjunctions >= 4.0 && < 5.0,
                        distributive >=0.2.2 && < 1.0,
                        process >= 1.1 && < 1.7,
diff --git a/src/Diagrams/Attributes/Compile.hs b/src/Diagrams/Attributes/Compile.hs
--- a/src/Diagrams/Attributes/Compile.hs
+++ b/src/Diagrams/Attributes/Compile.hs
@@ -25,6 +25,7 @@
 
 import           Control.Arrow       (second)
 import           Control.Lens        ((%~), (&), _Wrapping')
+import           Data.Kind           (Type)
 import qualified Data.HashMap.Strict as HM
 import           Data.Semigroup
 import           Data.Tree           (Tree (..))
@@ -39,8 +40,8 @@
 -- splitFills; it's done this way to facilitate testing.
 
 class (AttributeClass (AttrType code), Typeable (PrimType code)) => SplitAttribute code where
-  type AttrType code :: *
-  type PrimType code :: *
+  type AttrType code :: Type
+  type PrimType code :: Type
 
   primOK :: code -> PrimType code -> Bool
 
diff --git a/src/Diagrams/Backend/CmdLine.hs b/src/Diagrams/Backend/CmdLine.hs
--- a/src/Diagrams/Backend/CmdLine.hs
+++ b/src/Diagrams/Backend/CmdLine.hs
@@ -98,6 +98,7 @@
 import           Data.Data
 import           Data.Functor.Identity
 import           Data.IORef
+import           Data.Kind                 (Type)
 import           Data.List                 (delete)
 import           Data.Maybe                (fromMaybe)
 import           Data.Monoid
@@ -220,11 +221,17 @@
 --   Taken from Options.Applicative.Extra but without the
 --   short option 'h'.  We want the 'h' for Height.
 helper' :: Parser (a -> a)
-helper' = abortOption ShowHelpText $ mconcat
+helper' = abortOption param $ mconcat
   [ long "help"
   , short '?'
   , help "Show this help text"
   ]
+  where
+#if MIN_VERSION_optparse_applicative(0,16,0)
+    param = ShowHelpText Nothing
+#else
+    param = ShowHelpText 
+#endif
 
 -- | Apply a parser to the command line that includes the standard
 --   program description and help behavior.  Results in parsed commands
@@ -355,8 +362,8 @@
 --   at once, and a type @'ResultOf' d@ that is the type of the final result from
 --   some base case instance.
 class ToResult d where
-  type Args d :: *
-  type ResultOf d :: *
+  type Args d :: Type
+  type ResultOf d :: Type
 
   toResult :: d -> Args d -> ResultOf d
 
@@ -430,7 +437,7 @@
 class Mainable d where
   -- | Associated type that describes the options which need to be parsed
   -- from the command-line and passed to @mainRender@.
-  type MainOpts d :: *
+  type MainOpts d :: Type
 
   -- | This method invokes the command-line parser resulting in an options
   -- value or ending the program with an error or help message.
diff --git a/src/Diagrams/BoundingBox.hs b/src/Diagrams/BoundingBox.hs
--- a/src/Diagrams/BoundingBox.hs
+++ b/src/Diagrams/BoundingBox.hs
@@ -80,7 +80,7 @@
 type instance N (NonEmptyBoundingBox v n) = n
 
 fromNonEmpty :: NonEmptyBoundingBox v n -> BoundingBox v n
-fromNonEmpty = BoundingBox . Option . Just
+fromNonEmpty = BoundingBox . Just
 
 fromMaybeEmpty :: Maybe (NonEmptyBoundingBox v n) -> BoundingBox v n
 fromMaybeEmpty = maybe emptyBox fromNonEmpty
@@ -95,7 +95,7 @@
 -- | A bounding box is an axis-aligned region determined by two points
 --   indicating its \"lower\" and \"upper\" corners.  It can also represent
 --   an empty bounding box - the points are wrapped in @Maybe@.
-newtype BoundingBox v n = BoundingBox (Option (NonEmptyBoundingBox v n))
+newtype BoundingBox v n = BoundingBox (Maybe (NonEmptyBoundingBox v n))
   deriving (Eq, Functor)
 
 deriving instance (Additive v, Ord n) => Semigroup (BoundingBox v n)
@@ -166,7 +166,7 @@
 -- | An empty bounding box.  This is the same thing as @mempty@, but it doesn't
 --   require the same type constraints that the @Monoid@ instance does.
 emptyBox :: BoundingBox v n
-emptyBox = BoundingBox $ Option Nothing
+emptyBox = BoundingBox Nothing
 
 -- | Create a bounding box from a point that is component-wise @(<=)@ than the
 --   other.  If this is not the case, then @mempty@ is returned.
@@ -196,17 +196,17 @@
 
 -- | Queries whether the BoundingBox is empty.
 isEmptyBox :: BoundingBox v n -> Bool
-isEmptyBox (BoundingBox (Option Nothing)) = True
+isEmptyBox (BoundingBox Nothing) = True
 isEmptyBox _                              = False
 
 -- | Gets the lower and upper corners that define the bounding box.
 getCorners :: BoundingBox v n -> Maybe (Point v n, Point v n)
-getCorners (BoundingBox p) = nonEmptyCorners <$> getOption p
+getCorners (BoundingBox p) = nonEmptyCorners <$> p
 
 -- | Computes all of the corners of the bounding box.
 getAllCorners :: (Additive v, Traversable v) => BoundingBox v n -> [Point v n]
-getAllCorners (BoundingBox (Option Nothing)) = []
-getAllCorners (BoundingBox (Option (Just (NonEmptyBoundingBox (l, u)))))
+getAllCorners (BoundingBox Nothing) = []
+getAllCorners (BoundingBox (Just (NonEmptyBoundingBox (l, u))))
   = T.sequence (liftI2 (\a b -> [a,b]) l u)
 
 -- | Get the size of the bounding box - the vector from the (component-wise)
diff --git a/src/Diagrams/Combinators.hs b/src/Diagrams/Combinators.hs
--- a/src/Diagrams/Combinators.hs
+++ b/src/Diagrams/Combinators.hs
@@ -165,7 +165,7 @@
   => n -> v n -> QDiagram b v n m -> QDiagram b v n m
 deformEnvelope s v = over (envelope . _Wrapping Envelope) deformE
   where
-    deformE = Option . fmap deformE' . getOption
+    deformE = fmap deformE'
     deformE' env v'
         | dp > 0    = Max $ getMax (env v') + (dp * s) / quadrance v'
         | otherwise = env v'
diff --git a/src/Diagrams/Coordinates.hs b/src/Diagrams/Coordinates.hs
--- a/src/Diagrams/Coordinates.hs
+++ b/src/Diagrams/Coordinates.hs
@@ -19,8 +19,8 @@
     )
     where
 
+import           Data.Kind       (Type)
 import           Diagrams.Points
-
 import           Linear          (V2 (..), V3 (..), V4 (..))
 
 -- | Types which are instances of the @Coordinates@ class can be
@@ -36,13 +36,13 @@
 class Coordinates c where
 
   -- | The type of the final coordinate.
-  type FinalCoord c    :: *
+  type FinalCoord c    :: Type
 
   -- | The type of everything other than the final coordinate.
-  type PrevDim c       :: *
+  type PrevDim c       :: Type
 
   -- | Decomposition of @c@ into applications of ':&'.
-  type Decomposition c :: *
+  type Decomposition c :: Type
     -- Decomposition c = Decomposition (PrevDim c) :& FinalCoord c  (essentially)
 
   -- | Construct a value of type @c@ by providing something of one
diff --git a/src/Diagrams/Parametric.hs b/src/Diagrams/Parametric.hs
--- a/src/Diagrams/Parametric.hs
+++ b/src/Diagrams/Parametric.hs
@@ -22,12 +22,13 @@
 
   ) where
 
+import           Data.Kind (Type)
 import           Diagrams.Core.V
 import qualified Numeric.Interval.Kaucher as I
 
 -- | Codomain of parametric classes.  This is usually either @(V p)@, for relative
 --   vector results, or @(Point (V p))@, for functions with absolute coordinates.
-type family Codomain p :: * -> *
+type family Codomain p :: Type -> Type
 
 -- | Type class for parametric functions.
 class Parametric p where
diff --git a/src/Diagrams/Trail.hs b/src/Diagrams/Trail.hs
--- a/src/Diagrams/Trail.hs
+++ b/src/Diagrams/Trail.hs
@@ -311,7 +311,7 @@
 --   (along with a default value) to a function on an entire trail.
 trailMeasure :: ( SegMeasure v n :>: m, FT.Measured (SegMeasure v n) t )
              => a -> (m -> a) -> t -> a
-trailMeasure d f = option d f . get . FT.measure
+trailMeasure d f = maybe d f . get . FT.measure
 
 -- | Compute the number of segments of anything measured by
 --   'SegMeasure' (/e.g./ @SegMeasure@ itself, @Segment@, @SegTree@,
diff --git a/src/Diagrams/Transform.hs b/src/Diagrams/Transform.hs
--- a/src/Diagrams/Transform.hs
+++ b/src/Diagrams/Transform.hs
@@ -125,4 +125,4 @@
 -- @
 translated :: (InSpace v n a, SameSpace a b, Transformable a, Transformable b)
            => v n -> Iso a b a b
-translated = transformed . translation
+translated v = transformed $ translation v
diff --git a/src/Diagrams/Transform/Matrix.hs b/src/Diagrams/Transform/Matrix.hs
--- a/src/Diagrams/Transform/Matrix.hs
+++ b/src/Diagrams/Transform/Matrix.hs
@@ -30,7 +30,7 @@
 
 -- | Build a matrix from a 'Transformation', ignoring the translation.
 mkMat :: (HasBasis v, Num n) => Transformation v n -> v (v n)
-mkMat t = distribute . tabulate $ apply t . unit . el
+mkMat t = distribute . tabulate $ apply t . unit . (\x -> el x)
 
 -- | Build a 3D transformation matrix in homogeneous coordinates from
 --   a 'Transformation V3'.
diff --git a/src/Diagrams/TwoD/Arrow.hs b/src/Diagrams/TwoD/Arrow.hs
--- a/src/Diagrams/TwoD/Arrow.hs
+++ b/src/Diagrams/TwoD/Arrow.hs
@@ -401,7 +401,7 @@
     -- uniformly as the transformation applied to the entire arrow.
     -- See https://github.com/diagrams/diagrams-lib/issues/112.
     delayedArrow da g n =
-      let (trans, globalSty) = option mempty untangle . fst $ da
+      let (trans, globalSty) = maybe mempty untangle . fst $ da
       in  dArrow globalSty trans len g n
 
     -- Build an arrow and set its endpoints to the image under tr of origin and (len,0).
diff --git a/src/Diagrams/TwoD/Image.hs b/src/Diagrams/TwoD/Image.hs
--- a/src/Diagrams/TwoD/Image.hs
+++ b/src/Diagrams/TwoD/Image.hs
@@ -38,6 +38,7 @@
 import           Codec.Picture
 
 import           Data.Colour          (AlphaColour)
+import           Data.Kind            (Type)
 import           Data.Semigroup
 import           Data.Typeable        (Typeable)
 
@@ -56,12 +57,12 @@
 
 data Embedded deriving Typeable
 data External deriving Typeable
-data Native (t :: *) deriving Typeable
+data Native (t :: Type) deriving Typeable
 
 -- | 'ImageData' is either a JuicyPixels @DynamicImage@ tagged as 'Embedded' or
 --   a reference tagged as 'External'. Additionally 'Native' is provided for
 --   external libraries to hook into.
-data ImageData :: * -> * where
+data ImageData :: Type -> Type where
   ImageRaster :: DynamicImage -> ImageData Embedded
   ImageRef    :: FilePath -> ImageData External
   ImageNative :: t -> ImageData (Native t)
@@ -71,7 +72,7 @@
 --   Will typically be created by @loadImageEmb@ or @loadImageExt@ which,
 --   will handle setting the width and height to the actual width and height
 --   of the image.
-data DImage :: * -> * -> * where
+data DImage :: Type -> Type -> Type where
   DImage :: ImageData t -> Int -> Int -> Transformation V2 n -> DImage n t
   deriving Typeable
 
diff --git a/src/Diagrams/TwoD/Transform.hs b/src/Diagrams/TwoD/Transform.hs
--- a/src/Diagrams/TwoD/Transform.hs
+++ b/src/Diagrams/TwoD/Transform.hs
@@ -98,7 +98,7 @@
 -- @
 rotated :: (InSpace V2 n a, Floating n, SameSpace a b, Transformable a, Transformable b)
         => Angle n -> Iso a b a b
-rotated = transformed . rotation
+rotated a = transformed $ rotation a
 
 -- | @rotationAbout p@ is a rotation about the point @p@ (instead of
 --   around the local origin).
