diff --git a/CHANGELOG.md b/CHANGELOG.md
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -24,6 +24,20 @@
 
 [KaC]: <https://keepachangelog.com/en/1.0.0/>
 
+## 0.6.0.0 (2023-05-28)
+
+### Breaking
+
+* Add support for `optparse-applicative` `0.18`
+
+### Non-Breaking
+
+* Bump `ansi-wl-pprint` dependency version upper bound
+* Bump `MonadRandom` dependency version upper bound
+* Bump `transformers` dependency version upper bound
+* Bump `unix-compat` dependency version upper bound
+* Adjust dependency constraints to match tested versions
+
 ## 0.5.0.1 (2022-03-02)
 
 ### Non-Breaking
diff --git a/LICENSE b/LICENSE
--- a/LICENSE
+++ b/LICENSE
@@ -1,6 +1,6 @@
 The MIT License
 
-Copyright (c) 2019-2022 Travis Cardwell
+Copyright (c) 2019-2023 Travis Cardwell
 
 Permission is hereby granted, free of charge, to any person obtaining a copy
 of this software and associated documentation files (the "Software"), to deal
diff --git a/README.md b/README.md
--- a/README.md
+++ b/README.md
@@ -94,40 +94,62 @@
 
 ### Usage
 
-See the [`phatsort`](doc/phatsort.1.md) and [`seqcp`](doc/seqcp.1.md) man
-pages for usage information.
+See the [`phatsort`][] and [`seqcp`][] man pages for usage information.
 
+[`phatsort`]: <doc/phatsort.1.md>
+[`seqcp`]: <doc/seqcp.1.md>
+
 ## Related Software
 
-[`FATSort`](https://fatsort.sourceforge.io/) is a command-line utility that
-sorts unmounted FAT filesystems by direct manipulation of the FAT tables.
-Unfortunately, there are many devices for which this does not work.
+[`FATSort`][] is a command-line utility that sorts unmounted FAT filesystems
+by direct manipulation of the FAT tables.  Unfortunately, there are many
+devices for which this does not work.
 
-[`YAFS`](http://www.luisrios.eti.br/public/en_us/projects/yafs/) is a
-command-line utility that sorts unmounted FAT filesystems by direct
-manipulation of the FAT tables.
-[`Visual YAFS`](http://www.luisrios.eti.br/public/en_us/projects/visual_yafs/)
-provides a GUI.  I have not tried either of these.
+[`YAFS`][] is a command-line utility that sorts unmounted FAT filesystems by
+direct manipulation of the FAT tables.  [`Visual YAFS`][] provides a GUI.  I
+have not tried either of these.
 
-[`DriveSort`](http://www.anerty.net/software/file/DriveSort/) is Windows GUI
-software that sorts unmounted FAT filesystems by direct manipulation of the
-FAT tables.  I have not tried it.
+[`DriveSort`][] is Windows GUI software that sorts unmounted FAT filesystems
+by direct manipulation of the FAT tables.  I have not tried it.
 
+[`FATSort`]: <https://fatsort.sourceforge.io/>
+[`YAFS`]: <http://www.luisrios.eti.br/public/en_us/projects/yafs/>
+[`Visual YAFS`]: <http://www.luisrios.eti.br/public/en_us/projects/visual_yafs/>
+[`DriveSort`]: <http://www.anerty.net/software/file/DriveSort/>
+
 ## Project
 
 ### Links
 
 * Hackage: <https://hackage.haskell.org/package/phatsort>
 * Stackage: <https://www.stackage.org/package/phatsort>
+* Flora: <https://flora.pm/packages/@hackage/phatsort>
 * GitHub: <https://github.com/ExtremaIS/phatsort-haskell>
 * GitHub Actions CI: <https://github.com/ExtremaIS/phatsort-haskell/actions>
 
+### Branches
+
+The `main` branch is reserved for releases.  It may be considered stable, and
+`HEAD` is always the latest release.
+
+The `develop` branch is the primary development branch.  It contains changes
+that have not yet been released, and it is not necessarily stable.
+
+[Hackage revisions][] are made for metadata changes, such as relaxation of
+constraints when new versions of dependencies are released.  The
+`phatsort.cabal` metadata in the `main` branch may therefore not match that of
+Hackage.  The `phatsort.cabal` metadata in the `develop` branch may match,
+*unless* work is being done on a new release that contains other changes.
+
+[Hackage revisions]: <https://github.com/haskell-infra/hackage-trustees/blob/master/revisions-information.md#hackage-metadata-revisions--what-they-are-how-they-work>
+
 ### Tags
 
 All releases are tagged in the `main` branch.  Release tags are signed using
-the
-[`security@extrema.is` GPG key](http://keys.gnupg.net/pks/lookup?op=vindex&fingerprint=on&search=0x1D484E4B4705FADF).
+the [`security@extrema.is` GPG key][].
 
+[`security@extrema.is` GPG key]: <https://keyserver.ubuntu.com/pks/lookup?search=0x1D484E4B4705FADF&fingerprint=on&op=index>
+
 ### Contribution
 
 Issues and feature requests are tracked on GitHub:
@@ -137,6 +159,8 @@
 
 ### License
 
-This project is released under the
-[MIT License](https://opensource.org/licenses/MIT) as specified in the
-[`LICENSE`](LICENSE) file.
+This project is released under the [MIT License][] as specified in the
+[`LICENSE`][] file.
+
+[MIT License]: <https://opensource.org/licenses/MIT>
+[`LICENSE`]: <LICENSE>
diff --git a/app/LibOA.hs b/app/LibOA.hs
--- a/app/LibOA.hs
+++ b/app/LibOA.hs
@@ -2,22 +2,28 @@
 -- |
 -- Module      : LibOA
 -- Description : supplementary functions for optparse-applicative
--- Copyright   : Copyright (c) 2019-2022 Travis Cardwell
+-- Copyright   : Copyright (c) 2019-2023 Travis Cardwell
 -- License     : MIT
 --
 -- This is a collection of functions that I often use with
 -- @optparse-applicative@.  I do not feel that it is worth maintaining yet
 -- another helper package on Hackage, so I just copy the code to different
 -- projects as required.  If the library grows to a substantial size or others
--- with to use it, I will reconsider.
+-- want to use it, I will reconsider.
 --
--- Revision: 2022-01-02
+-- Revision: 2023-05-26
 ------------------------------------------------------------------------------
 
 {-# LANGUAGE CPP #-}
 {-# LANGUAGE LambdaCase #-}
 {-# LANGUAGE TupleSections #-}
 
+#if defined(MIN_VERSION_ansi_wl_pprint)
+#if MIN_VERSION_ansi_wl_pprint (1,0,2)
+{-# OPTIONS_GHC -Wno-warnings-deprecations #-}
+#endif
+#endif
+
 module LibOA
   ( -- * Options
     -- $Options
@@ -28,14 +34,23 @@
     -- * Help
   , (<||>)
   , section
+  , section'
   , table
   , table_
   , vspace
+    -- ** Compatibility
+  , Doc
+  , (<$$>)
+  , empty
+  , string
+  , vcat
   ) where
 
 -- https://hackage.haskell.org/package/ansi-wl-pprint
+#if !MIN_VERSION_optparse_applicative (0,18,0)
 import qualified Text.PrettyPrint.ANSI.Leijen as Doc
 import Text.PrettyPrint.ANSI.Leijen (Doc)
+#endif
 
 -- https://hackage.haskell.org/package/base
 import Data.List (intersperse, transpose)
@@ -50,8 +65,16 @@
 import qualified Options.Applicative.Builder.Internal as OABI
 #endif
 import qualified Options.Applicative.Common as OAC
+#if MIN_VERSION_optparse_applicative (0,18,0)
+import Options.Applicative.Help.Pretty (Doc)
+#endif
 import qualified Options.Applicative.Types as OAT
 
+-- https://hackage.haskell.org/package/prettyprinter
+#if MIN_VERSION_optparse_applicative (0,18,0)
+import qualified Prettyprinter as Doc
+#endif
+
 ------------------------------------------------------------------------------
 -- $Options
 --
@@ -103,8 +126,12 @@
 commands :: OA.Parser a -> [String]
 commands =
     let go _ opt = case OAT.optMain opt of
+#if MIN_VERSION_optparse_applicative (0,18,0)
+           OAT.CmdReader _ cmdPs -> reverse $ fst <$> cmdPs
+#else
            OAT.CmdReader _ cmds _ -> reverse cmds
-           _otherReader           -> []
+#endif
+           _otherReader -> []
     in  concat . OAC.mapParser go
 
 ------------------------------------------------------------------------------
@@ -115,22 +142,26 @@
 d1 <||> d2 = d1 <> Doc.line <> Doc.line <> d2
 infixr 5 <||>
 
--- | Create a section with a title and indented body
+-- | Create a section with a title and body indented by 2 spaces
 section :: String -> Doc -> Doc
-section title = (Doc.text title Doc.<$$>) . Doc.indent 2
+section = section' 2
 
+-- | Create a section with a title and body indented by specified spaces
+section' :: Int -> String -> Doc -> Doc
+section' numSpaces title = (string title <$$>) . Doc.indent numSpaces
+
 -- | Create a table, with formatting
 table :: Int -> [[(String, Doc -> Doc)]] -> Doc
 table sep rows = Doc.vcat $
-    map (fromMaybe Doc.empty . foldr go Nothing . zip lengths) rows
+    map (fromMaybe empty . foldr go Nothing . zip lengths) rows
   where
     lengths :: [Int]
     lengths = map ((+) sep . maximum . map (length . fst)) $ transpose rows
 
     go :: (Int, (String, Doc -> Doc)) -> Maybe Doc -> Maybe Doc
     go (len, (s, f)) = Just . \case
-      Just doc -> Doc.fill len (f $ Doc.string s) <> doc
-      Nothing  -> f $ Doc.string s
+      Just doc -> Doc.fill len (f $ string s) <> doc
+      Nothing  -> f $ string s
 
 -- | Create a table, without formatting
 table_ :: Int -> [[String]] -> Doc
@@ -139,3 +170,30 @@
 -- | Vertically space documents with blank lines between them
 vspace :: [Doc] -> Doc
 vspace = mconcat . intersperse (Doc.line <> Doc.line)
+
+------------------------------------------------------------------------------
+-- $Compatibility
+
+(<$$>) :: Doc -> Doc -> Doc
+#if MIN_VERSION_optparse_applicative (0,18,0)
+l <$$> r = l <> Doc.line <> r
+#else
+(<$$>) = (Doc.<$$>)
+#endif
+
+empty :: Doc
+#if MIN_VERSION_optparse_applicative (0,18,0)
+empty = Doc.emptyDoc
+#else
+empty = Doc.empty
+#endif
+
+string :: String -> Doc
+#if MIN_VERSION_optparse_applicative (0,18,0)
+string = Doc.pretty
+#else
+string = Doc.string
+#endif
+
+vcat :: [Doc] -> Doc
+vcat = Doc.vcat
diff --git a/app/Options.hs b/app/Options.hs
--- a/app/Options.hs
+++ b/app/Options.hs
@@ -2,15 +2,20 @@
 -- |
 -- Module      : Options
 -- Description : CLI options and help documentation
--- Copyright   : Copyright (c) 2019-2022 Travis Cardwell
+-- Copyright   : Copyright (c) 2019-2023 Travis Cardwell
 -- License     : MIT
 ------------------------------------------------------------------------------
 
-module Options where
+{-# LANGUAGE CPP #-}
 
--- https://hackage.haskell.org/package/ansi-wl-pprint
-import Text.PrettyPrint.ANSI.Leijen (Doc)
+#if defined(MIN_VERSION_ansi_wl_pprint)
+#if MIN_VERSION_ansi_wl_pprint (1,0,2)
+{-# OPTIONS_GHC -Wno-warnings-deprecations #-}
+#endif
+#endif
 
+module Options where
+
 -- https://hackage.haskell.org/package/base
 import Data.Bool (bool)
 
@@ -39,7 +44,7 @@
 
 ------------------------------------------------------------------------------
 
-exitCodeHelp :: Doc
+exitCodeHelp :: LibOA.Doc
 exitCodeHelp = LibOA.section "Exit codes:" $ LibOA.table_ 2
     [ ["0", "no error"]
     , ["1", "execution error"]
@@ -64,7 +69,7 @@
 
 ------------------------------------------------------------------------------
 
-firstTypeHelp :: Doc
+firstTypeHelp :: LibOA.Doc
 firstTypeHelp = LibOA.section "TYPE choices:" $ LibOA.table_ 2
     [ ["dirs", "sort directories before files"]
     , ["files", "sort files before directories"]
@@ -98,7 +103,7 @@
 
 ------------------------------------------------------------------------------
 
-orderHelp :: Doc
+orderHelp :: LibOA.Doc
 orderHelp = LibOA.section "ORDER choices:" $ LibOA.table_ 2
     [ ["name", "sort by filename"]
     , ["time", "sort by modification time"]
diff --git a/app/phatsort.hs b/app/phatsort.hs
--- a/app/phatsort.hs
+++ b/app/phatsort.hs
@@ -2,7 +2,7 @@
 -- |
 -- Module      : Main
 -- Description : phatsort CLI
--- Copyright   : Copyright (c) 2019-2022 Travis Cardwell
+-- Copyright   : Copyright (c) 2019-2023 Travis Cardwell
 -- License     : MIT
 ------------------------------------------------------------------------------
 
diff --git a/app/seqcp.hs b/app/seqcp.hs
--- a/app/seqcp.hs
+++ b/app/seqcp.hs
@@ -2,7 +2,7 @@
 -- |
 -- Module      : Main
 -- Description : seqcp CLI
--- Copyright   : Copyright (c) 2019-2022 Travis Cardwell
+-- Copyright   : Copyright (c) 2019-2023 Travis Cardwell
 -- License     : MIT
 ------------------------------------------------------------------------------
 
diff --git a/phatsort.cabal b/phatsort.cabal
--- a/phatsort.cabal
+++ b/phatsort.cabal
@@ -1,5 +1,5 @@
 name:           phatsort
-version:        0.5.0.1
+version:        0.6.0.0
 category:       Utils
 synopsis:       FAT filesystem sort utility
 description:
@@ -11,7 +11,7 @@
 bug-reports:    https://github.com/ExtremaIS/phatsort-haskell/issues
 author:         Travis Cardwell <travis.cardwell@extrema.is>
 maintainer:     Travis Cardwell <travis.cardwell@extrema.is>
-copyright:      Copyright (c) 2019-2022 Travis Cardwell
+copyright:      Copyright (c) 2019-2023 Travis Cardwell
 license:        MIT
 license-file:   LICENSE
 
@@ -24,7 +24,8 @@
    || ==8.8.4
    || ==8.10.7
    || ==9.0.2
-   || ==9.2.1
+   || ==9.2.8
+   || ==9.4.5
 
 extra-source-files:
   CHANGELOG.md
@@ -34,9 +35,11 @@
   type: git
   location: https://github.com/ExtremaIS/phatsort-haskell.git
 
-flag write-hie
-  description: write .hie files
+-- This flag is referenced in the Stack build-constraints.yaml configuration.
+flag optparse-applicative_ge_0_18
+  description: Use optparse-applicative 0.18 or newer
   default: False
+  manual: False
 
 library
   hs-source-dirs: src
@@ -56,20 +59,17 @@
     other-modules:
         PhatSort.Monad.Sync.Unistd
   build-depends:
-      base >=4.7 && <5
-    , directory >=1.3 && <1.4
-    , filepath >=1.4 && <1.5
-    , MonadRandom >=0.5 && <0.6
+      base >=4.10.1 && <4.18
+    , directory >=1.3.0.2 && <1.4
+    , filepath >=1.4.1.2 && <1.5
+    , MonadRandom >=0.5 && <0.7
     , random-shuffle >=0.0.4 && <0.1
-    , transformers >=0.5 && <0.6
-    , unix-compat >=0.5 && <0.6
+    , transformers >=0.5 && <0.7
+    , unix-compat >=0.5 && <0.8
   default-language: Haskell2010
   default-extensions:
       OverloadedStrings
-  if flag(write-hie)
-    ghc-options: -Wall -fwrite-ide-info -hiedir=.hie
-  else
-    ghc-options: -Wall
+  ghc-options: -Wall
 
 executable phatsort
   hs-source-dirs: app
@@ -78,15 +78,18 @@
       LibOA
     , Options
   build-depends:
-      ansi-wl-pprint >=0.6 && <0.7
-    , base
-    , optparse-applicative >=0.14 && <0.18
+      base
     , phatsort
-  default-language: Haskell2010
-  if flag(write-hie)
-    ghc-options: -Wall -fwrite-ide-info -hiedir=.hie
+  if flag(optparse-applicative_ge_0_18)
+    build-depends:
+        optparse-applicative >=0.18 && <0.19
+      , prettyprinter >=1.7.1 && <1.8
   else
-    ghc-options: -Wall
+    build-depends:
+        ansi-wl-pprint >=0.6.8 && <1.1
+      , optparse-applicative >=0.13 && <0.18
+  default-language: Haskell2010
+  ghc-options: -Wall
 
 executable seqcp
   hs-source-dirs: app
@@ -95,15 +98,18 @@
       LibOA
     , Options
   build-depends:
-      ansi-wl-pprint >=0.6 && <0.7
-    , base
-    , optparse-applicative >=0.14 && <0.18
+      base
     , phatsort
-  default-language: Haskell2010
-  if flag(write-hie)
-    ghc-options: -Wall -fwrite-ide-info -hiedir=.hie
+  if flag(optparse-applicative_ge_0_18)
+    build-depends:
+        optparse-applicative >=0.18 && <0.19
+      , prettyprinter >=1.7.1 && <1.8
   else
-    ghc-options: -Wall
+    build-depends:
+        ansi-wl-pprint >=0.6.8 && <1.1
+      , optparse-applicative >=0.13 && <0.18
+  default-language: Haskell2010
+  ghc-options: -Wall
 
 test-suite phatsort-test
   type: exitcode-stdio-1.0
@@ -113,9 +119,9 @@
       base
     , MonadRandom
     , phatsort
-    , tasty >=1.0 && <1.5
-    , tasty-hunit >=0.10 && <0.11
-    , transformers >=0.5 && <0.7
+    , tasty >=0.12 && <1.5
+    , tasty-hunit >=0.8 && <0.11
+    , transformers
   if impl(ghc >= 8.6.1)
     other-modules:
         PhatSort.Cmd.PhatSort.Mock
diff --git a/src/PhatSort.hs b/src/PhatSort.hs
--- a/src/PhatSort.hs
+++ b/src/PhatSort.hs
@@ -2,7 +2,7 @@
 -- |
 -- Module      : PhatSort
 -- Description : metadata
--- Copyright   : Copyright (c) 2019-2022 Travis Cardwell
+-- Copyright   : Copyright (c) 2019-2023 Travis Cardwell
 -- License     : MIT
 ------------------------------------------------------------------------------
 
diff --git a/src/PhatSort/Cmd/PhatSort.hs b/src/PhatSort/Cmd/PhatSort.hs
--- a/src/PhatSort/Cmd/PhatSort.hs
+++ b/src/PhatSort/Cmd/PhatSort.hs
@@ -2,7 +2,7 @@
 -- |
 -- Module      : PhatSort.Cmd.PhatSort
 -- Description : phatsort command implementation
--- Copyright   : Copyright (c) 2019-2022 Travis Cardwell
+-- Copyright   : Copyright (c) 2019-2023 Travis Cardwell
 -- License     : MIT
 ------------------------------------------------------------------------------
 
diff --git a/src/PhatSort/Cmd/SeqCp.hs b/src/PhatSort/Cmd/SeqCp.hs
--- a/src/PhatSort/Cmd/SeqCp.hs
+++ b/src/PhatSort/Cmd/SeqCp.hs
@@ -2,7 +2,7 @@
 -- |
 -- Module      : PhatSort.Cmd.SeqCp
 -- Description : seqcp command implementation
--- Copyright   : Copyright (c) 2019-2022 Travis Cardwell
+-- Copyright   : Copyright (c) 2019-2023 Travis Cardwell
 -- License     : MIT
 ------------------------------------------------------------------------------
 
diff --git a/src/PhatSort/Monad/FileSystem.hs b/src/PhatSort/Monad/FileSystem.hs
--- a/src/PhatSort/Monad/FileSystem.hs
+++ b/src/PhatSort/Monad/FileSystem.hs
@@ -2,7 +2,7 @@
 -- |
 -- Module      : PhatSort.Monad.FileSystem
 -- Description : filesystem I/O
--- Copyright   : Copyright (c) 2019-2022 Travis Cardwell
+-- Copyright   : Copyright (c) 2019-2023 Travis Cardwell
 -- License     : MIT
 ------------------------------------------------------------------------------
 
diff --git a/src/PhatSort/Monad/Stdio.hs b/src/PhatSort/Monad/Stdio.hs
--- a/src/PhatSort/Monad/Stdio.hs
+++ b/src/PhatSort/Monad/Stdio.hs
@@ -2,7 +2,7 @@
 -- |
 -- Module      : PhatSort.Monad.Stdio
 -- Description : standard I/O
--- Copyright   : Copyright (c) 2019-2022 Travis Cardwell
+-- Copyright   : Copyright (c) 2019-2023 Travis Cardwell
 -- License     : MIT
 ------------------------------------------------------------------------------
 
diff --git a/src/PhatSort/Monad/Sync.hs b/src/PhatSort/Monad/Sync.hs
--- a/src/PhatSort/Monad/Sync.hs
+++ b/src/PhatSort/Monad/Sync.hs
@@ -2,7 +2,7 @@
 -- |
 -- Module      : PhatSort.Monad.Sync
 -- Description : commit all data in filesystem buffers
--- Copyright   : Copyright (c) 2019-2022 Travis Cardwell
+-- Copyright   : Copyright (c) 2019-2023 Travis Cardwell
 -- License     : MIT
 ------------------------------------------------------------------------------
 
diff --git a/src/PhatSort/Monad/Sync/Unistd.hs b/src/PhatSort/Monad/Sync/Unistd.hs
--- a/src/PhatSort/Monad/Sync/Unistd.hs
+++ b/src/PhatSort/Monad/Sync/Unistd.hs
@@ -2,7 +2,7 @@
 -- |
 -- Module      : PhatSort.Monad.Sync.Unistd
 -- Description : sync implementation for POSIX systems
--- Copyright   : Copyright (c) 2019-2022 Travis Cardwell
+-- Copyright   : Copyright (c) 2019-2023 Travis Cardwell
 -- License     : MIT
 ------------------------------------------------------------------------------
 
diff --git a/src/PhatSort/Monad/Trans/Error.hs b/src/PhatSort/Monad/Trans/Error.hs
--- a/src/PhatSort/Monad/Trans/Error.hs
+++ b/src/PhatSort/Monad/Trans/Error.hs
@@ -2,7 +2,7 @@
 -- |
 -- Module      : PhatSort.Monad.Trans.Error
 -- Description : error monad transformer
--- Copyright   : Copyright (c) 2019-2022 Travis Cardwell
+-- Copyright   : Copyright (c) 2019-2023 Travis Cardwell
 -- License     : MIT
 ------------------------------------------------------------------------------
 
diff --git a/src/PhatSort/Script.hs b/src/PhatSort/Script.hs
--- a/src/PhatSort/Script.hs
+++ b/src/PhatSort/Script.hs
@@ -2,7 +2,7 @@
 -- |
 -- Module      : PhatSort.Script
 -- Description : script API
--- Copyright   : Copyright (c) 2019-2022 Travis Cardwell
+-- Copyright   : Copyright (c) 2019-2023 Travis Cardwell
 -- License     : MIT
 ------------------------------------------------------------------------------
 
diff --git a/src/PhatSort/SortOptions.hs b/src/PhatSort/SortOptions.hs
--- a/src/PhatSort/SortOptions.hs
+++ b/src/PhatSort/SortOptions.hs
@@ -2,7 +2,7 @@
 -- |
 -- Module      : PhatSort.SortOptions
 -- Description : sort options
--- Copyright   : Copyright (c) 2019-2022 Travis Cardwell
+-- Copyright   : Copyright (c) 2019-2023 Travis Cardwell
 -- License     : MIT
 ------------------------------------------------------------------------------
 
