diff --git a/CHANGELOG.md b/CHANGELOG.md
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -24,6 +24,17 @@
 
 [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
+* Adjust dependency constraints to match tested versions
+
 ## 0.5.0.0 (2022-03-01)
 
 ### 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
@@ -74,8 +74,10 @@
 
 ### Usage
 
-See the [`hr` man page](doc/hr.1.md) for usage information.
+See the [`hr` man page][] for usage information.
 
+[`hr` man page]: <doc/hr.1.md>
+
 #### Examples
 
 The rule fills with width of the terminal by default:
@@ -163,15 +165,34 @@
 
 * Hackage: <https://hackage.haskell.org/package/horizontal-rule>
 * Stackage: <https://www.stackage.org/package/horizontal-rule>
+* Flora: <https://flora.pm/packages/@hackage/horizontal-rule>
 * GitHub: <https://github.com/ExtremaIS/hr-haskell>
 * GitHub Actions CI: <https://github.com/ExtremaIS/hr-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
+`horizontal-rule.cabal` metadata in the `main` branch may therefore not match
+that of Hackage.  The `horizontal-rule.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:
@@ -181,6 +202,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/Main.hs b/app/Main.hs
--- a/app/Main.hs
+++ b/app/Main.hs
@@ -2,18 +2,22 @@
 -- |
 -- Module      : Main
 -- Description : hr: a horizontal rule for terminals
--- Copyright   : Copyright (c) 2019-2022 Travis Cardwell
+-- Copyright   : Copyright (c) 2019-2023 Travis Cardwell
 -- License     : MIT
 --
 -- See the README for details.
 ------------------------------------------------------------------------------
 
+{-# LANGUAGE CPP #-}
 {-# LANGUAGE RecordWildCards #-}
 
-module Main (main) where
+#if defined(MIN_VERSION_ansi_wl_pprint)
+#if MIN_VERSION_ansi_wl_pprint (1,0,2)
+{-# OPTIONS_GHC -Wno-warnings-deprecations #-}
+#endif
+#endif
 
--- https://hackage.haskell.org/package/ansi-wl-pprint
-import Text.PrettyPrint.ANSI.Leijen (Doc)
+module Main (main) where
 
 -- https://hackage.haskell.org/package/base
 import Control.Applicative (many, optional)
@@ -176,7 +180,7 @@
           , OA.footerDoc $ Just formatHelp
           ]
 
-    formatHelp :: Doc
+    formatHelp :: LibOA.Doc
     formatHelp = LibOA.section "FORMAT codes:" $ LibOA.table_ 2
       [ ["%Y", "four-digit year"]
       , ["%y", "two-digit year"]
diff --git a/horizontal-rule.cabal b/horizontal-rule.cabal
--- a/horizontal-rule.cabal
+++ b/horizontal-rule.cabal
@@ -1,5 +1,5 @@
 name:           horizontal-rule
-version:        0.5.0.0
+version:        0.6.0.0
 category:       Utils
 synopsis:       horizontal rule for the terminal
 description:
@@ -11,7 +11,7 @@
 bug-reports:    https://github.com/ExtremaIS/hr-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,9 @@
    || ==8.8.4
    || ==8.10.7
    || ==9.0.2
-   || ==9.2.1
+   || ==9.2.8
+   || ==9.4.5
+   || ==9.6.2
 
 extra-source-files:
   CHANGELOG.md
@@ -34,9 +36,11 @@
   type: git
   location: https://github.com/ExtremaIS/hr-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
@@ -46,16 +50,13 @@
   other-modules:
       Paths_horizontal_rule
   build-depends:
-      base >=4.7 && <5
-    , terminal-size >=0.3 && <0.4
+      base >=4.10.1 && <4.19
+    , terminal-size >=0.2 && <0.4
     , text >=1.2.3 && <2.1
   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 hr
   hs-source-dirs: app
@@ -63,12 +64,18 @@
   other-modules:
       LibOA
   build-depends:
-      ansi-wl-pprint >=0.6 && <0.7
-    , base
+      base
     , horizontal-rule
-    , optparse-applicative >=0.14 && <0.18
     , text
-    , time >=1.8 && <1.13
+    , time >=1.8.0.2 && <1.13
+  if flag(optparse-applicative_ge_0_18)
+    build-depends:
+        optparse-applicative >=0.18 && <0.19
+      , prettyprinter >=1.7.1 && <1.8
+  else
+    build-depends:
+        ansi-wl-pprint >=0.6.8 && <1.1
+      , optparse-applicative >=0.13 && <0.18
   default-language: Haskell2010
   ghc-options: -Wall
 
@@ -81,8 +88,8 @@
   build-depends:
       base
     , horizontal-rule
-    , tasty >=1.0 && <1.5
-    , tasty-hunit >=0.10 && <0.11
+    , tasty >=0.12 && <1.5
+    , tasty-hunit >=0.8 && <0.11
   if impl(ghc >= 8.6.1)
     other-modules:
         HR.Mock
diff --git a/src/HR.hs b/src/HR.hs
--- a/src/HR.hs
+++ b/src/HR.hs
@@ -2,7 +2,7 @@
 -- |
 -- Module      : HR
 -- Description : horizontal rule for terminals
--- Copyright   : Copyright (c) 2019-2022 Travis Cardwell
+-- Copyright   : Copyright (c) 2019-2023 Travis Cardwell
 -- License     : MIT
 --
 -- This library is meant to be imported qualified, as follows:
diff --git a/src/HR/Monad/Terminal.hs b/src/HR/Monad/Terminal.hs
--- a/src/HR/Monad/Terminal.hs
+++ b/src/HR/Monad/Terminal.hs
@@ -2,7 +2,7 @@
 -- |
 -- Module      : HR.Monad.Terminal
 -- Description : terminal output
--- Copyright   : Copyright (c) 2019-2022 Travis Cardwell
+-- Copyright   : Copyright (c) 2019-2023 Travis Cardwell
 -- License     : MIT
 ------------------------------------------------------------------------------
 
