diff --git a/changelog.md b/changelog.md
--- a/changelog.md
+++ b/changelog.md
@@ -1,3 +1,7 @@
+### 0.0.1.12 (2023-06-26)
+
+Raise language version to GHC2021
+
 ### 0.0.1.11 (2023-01-11)
 
 Support GHC 9.4
diff --git a/path-text-utf8.cabal b/path-text-utf8.cabal
--- a/path-text-utf8.cabal
+++ b/path-text-utf8.cabal
@@ -1,7 +1,7 @@
 cabal-version: 3.0
 
 name: path-text-utf8
-version: 0.0.1.11
+version: 0.0.1.12
 category: Filesystem, Text
 
 synopsis: Read and write UTF-8 text files
@@ -27,17 +27,19 @@
     location: https://github.com/typeclasses/path-text-utf8
 
 library
-    default-language: Haskell2010
+    default-language: GHC2021
     hs-source-dirs: src
     ghc-options: -Wall
-    default-extensions: BangPatterns NoImplicitPrelude
+    default-extensions:
+        BangPatterns
+        NoImplicitPrelude
 
     exposed-modules:
         Path.Text.UTF8
 
     build-depends:
-      , base ^>= 4.14 || ^>= 4.15 || ^>= 4.16 || ^>= 4.17
+      , base ^>= 4.16 || ^>= 4.17 || ^>= 4.18
       , bytestring ^>= 0.10.12 || ^>= 0.11
       , path ^>= 0.9.2
       , safe-exceptions ^>= 0.1.7
-      , text ^>= 1.2.4 || ^>= 2.0
+      , text ^>= 1.2.5 || ^>= 2.0
diff --git a/src/Path/Text/UTF8.hs b/src/Path/Text/UTF8.hs
--- a/src/Path/Text/UTF8.hs
+++ b/src/Path/Text/UTF8.hs
@@ -1,74 +1,75 @@
 -- | Read and write UTF-8 text files.
 module Path.Text.UTF8
-  (
-    {- * Reading    -} readFile, tryReadFile, ReadError (..),
-    {- * Writing    -} writeFile, tryWriteFile, WriteError,
-    {- * Re-exports -} IOError, UnicodeException (DecodeError),
-                       parseAbsFile, parseRelFile,
+  ( -- * Reading
+    readFile,
+    tryReadFile,
+    ReadError (..),
+
+    -- * Writing
+    writeFile,
+    tryWriteFile,
+    WriteError,
+
+    -- * Re-exports
+    IOError,
+    UnicodeException (DecodeError),
+    parseAbsFile,
+    parseRelFile,
   )
-  where
+where
 
--- base
+import Control.Exception.Safe qualified as Exception
+import Data.ByteString qualified as BS
 import Data.Either (Either (..))
 import Data.Functor ((<$>))
-import System.IO (IO)
-import System.IO.Error (IOError)
-
--- safe-exceptions
-import qualified Control.Exception.Safe as Exception
-
--- bytestring
-import qualified Data.ByteString as BS
-
--- text
 import Data.Text (Text)
+import Data.Text.Encoding qualified as TextEncoding
 import Data.Text.Encoding.Error (UnicodeException (..))
-import qualified Data.Text.Encoding as TextEncoding
-
--- path
 import Path (Path, parseAbsFile, parseRelFile)
-import qualified Path
+import Path qualified
+import System.IO (IO)
+import System.IO.Error (IOError)
 
-data ReadError =
-    ReadErrorIO IOError
+data ReadError
+  = ReadErrorIO IOError
   | ReadErrorDecode UnicodeException
 
 type WriteError = IOError
 
-{-| Read the contents of a UTF-8 encoded text file
-
-May throw 'IOError' or 'UnicodeException'. To handle these errors in 'Either'
-instead, use 'tryReadFile'. -}
+-- | Read the contents of a UTF-8 encoded text file
+--
+-- May throw 'IOError' or 'UnicodeException'. To handle these errors in 'Either'
+-- instead, use 'tryReadFile'.
 readFile :: Path base Path.File -> IO Text
 readFile path =
-    f <$> BS.readFile (Path.toFilePath path)
+  f <$> BS.readFile (Path.toFilePath path)
   where
     f bs = let !text = TextEncoding.decodeUtf8 bs in text
 
-{-| Read the contents of a UTF-8 encoded text file
-
-Any 'IOError' or 'UnicodeException' that occurs is caught and returned as a
-'ReadError' on the 'Left' side of the 'Either'. To throw these exceptions
-instead, use 'readFile'. -}
+-- | Read the contents of a UTF-8 encoded text file
+--
+-- Any 'IOError' or 'UnicodeException' that occurs is caught and returned as a
+-- 'ReadError' on the 'Left' side of the 'Either'. To throw these exceptions
+-- instead, use 'readFile'.
 tryReadFile :: Path base Path.File -> IO (Either ReadError Text)
 tryReadFile path =
-    f <$> Exception.tryIO (BS.readFile (Path.toFilePath path))
+  f <$> Exception.tryIO (BS.readFile (Path.toFilePath path))
   where
     f (Left e) = Left (ReadErrorIO e)
     f (Right bs) = first ReadErrorDecode (TextEncoding.decodeUtf8' bs)
 
-{-| Write text to a file in a UTF-8 encoding
-
-May throw 'IOError'. To handle this error in 'Either' instead, use
-'tryWriteFile'. -}
+-- | Write text to a file in a UTF-8 encoding
+--
+-- May throw 'IOError'. To handle this error in 'Either' instead, use
+-- 'tryWriteFile'.
 writeFile :: Path base Path.File -> Text -> IO ()
 writeFile path text =
-    BS.writeFile (Path.toFilePath path) (TextEncoding.encodeUtf8 text)
-
-{-| Write text to a file in a UTF-8 encoding
+  BS.writeFile (Path.toFilePath path) (TextEncoding.encodeUtf8 text)
 
-Any 'IOError' that occurs is caught and returned on the 'Left' side of the
-'Either'. To throw the exception instead, use 'writeFile'. -}
+-- | Write text to a file in a UTF-8 encoding
+--
+-- Any 'IOError' that occurs is caught and returned on the 'Left' side of the
+-- 'Either'. To throw the exception instead, use 'writeFile'.
 tryWriteFile :: Path base Path.File -> Text -> IO (Either WriteError ())
 tryWriteFile path text = Exception.tryIO (writeFile path text)
 
