diff --git a/CHANGELOG.md b/CHANGELOG.md
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,11 @@
 # Changelog
 
+## [0.4.2.2] - 2024-09-01
+
+### Added
+
+* `boundedEnumCodec`
+
 ## [0.4.2.1] - 2024-08-21
 
 ### Added
diff --git a/autodocodec.cabal b/autodocodec.cabal
--- a/autodocodec.cabal
+++ b/autodocodec.cabal
@@ -5,7 +5,7 @@
 -- see: https://github.com/sol/hpack
 
 name:           autodocodec
-version:        0.4.2.1
+version:        0.4.2.2
 synopsis:       Self-documenting encoder and decoder
 homepage:       https://github.com/NorfairKing/autodocodec#readme
 bug-reports:    https://github.com/NorfairKing/autodocodec/issues
diff --git a/src/Autodocodec.hs b/src/Autodocodec.hs
--- a/src/Autodocodec.hs
+++ b/src/Autodocodec.hs
@@ -102,6 +102,7 @@
 
     -- *** Enums
     shownBoundedEnumCodec,
+    boundedEnumCodec,
     stringConstCodec,
     enumCodec,
 
diff --git a/src/Autodocodec/Codec.hs b/src/Autodocodec/Codec.hs
--- a/src/Autodocodec/Codec.hs
+++ b/src/Autodocodec/Codec.hs
@@ -1907,6 +1907,33 @@
           )
       )
 
+-- | A codec for a 'Bounded' 'Enum' that uses the provided function to have the values correspond to literal 'Text' values.
+--
+--
+-- === Example usage
+--
+-- >>> data Fruit = Apple | Orange deriving (Show, Eq, Enum, Bounded)
+-- >>> :{
+--   let c = boundedEnumCodec $ \case
+--         Apple -> "foo"
+--         Orange -> "bar"
+-- :}
+--
+-- >>> toJSONVia c Apple
+-- String "foo"
+-- >>> JSON.parseMaybe (parseJSONVia c) (String "bar") :: Maybe Fruit
+-- Just Orange
+boundedEnumCodec ::
+  forall enum.
+  (Eq enum, Enum enum, Bounded enum) =>
+  (enum -> T.Text) ->
+  JSONCodec enum
+boundedEnumCodec showFunc =
+  let ls = [minBound .. maxBound]
+   in case NE.nonEmpty ls of
+        Nothing -> error "0 enum values ?!"
+        Just ne -> stringConstCodec (NE.map (\v -> (v, showFunc v)) ne)
+
 -- | A codec for a 'Bounded' 'Enum' that uses its 'Show' instance to have the values correspond to literal 'Text' values.
 --
 --
@@ -1922,11 +1949,7 @@
   forall enum.
   (Show enum, Eq enum, Enum enum, Bounded enum) =>
   JSONCodec enum
-shownBoundedEnumCodec =
-  let ls = [minBound .. maxBound]
-   in case NE.nonEmpty ls of
-        Nothing -> error "0 enum values ?!"
-        Just ne -> stringConstCodec (NE.map (\v -> (v, T.pack (show v))) ne)
+shownBoundedEnumCodec = boundedEnumCodec (T.pack . show)
 
 -- | Helper function for 'optionalFieldOrNullWith' and 'optionalFieldOrNull'.
 --
