diff --git a/CHANGELOG.md b/CHANGELOG.md
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,11 @@
 # Changelog
 
+## [0.1.0.2] - 2022-06-24
+
+### Added
+
+* `scientificWithBoundsCodec` for a `NumberCodec` with bounds but without a name.
+
 ## [0.1.0.1] - 2022-05-03
 
 ### Changed
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.1.0.1
+version:        0.1.0.2
 synopsis:       Self-documenting encoder and decoder
 homepage:       https://github.com/NorfairKing/autodocodec#readme
 bug-reports:    https://github.com/NorfairKing/autodocodec/issues
@@ -64,4 +64,8 @@
   build-depends:
       base >=4.7 && <5
     , doctest
+  if impl(GHC < 9.0)
+    buildable: True
+  else
+    buildable: False
   default-language: Haskell2010
diff --git a/src/Autodocodec.hs b/src/Autodocodec.hs
--- a/src/Autodocodec.hs
+++ b/src/Autodocodec.hs
@@ -64,6 +64,7 @@
     textCodec,
     stringCodec,
     scientificCodec,
+    scientificWithBoundsCodec,
     valueCodec,
 
     -- *** Integral codecs
diff --git a/src/Autodocodec/Class.hs b/src/Autodocodec/Class.hs
--- a/src/Autodocodec/Class.hs
+++ b/src/Autodocodec/Class.hs
@@ -166,7 +166,6 @@
   Text ->
   -- | Documentation
   Text ->
-  -- |
   ObjectCodec output output
 requiredField key = requiredFieldWith key codec
 
@@ -175,7 +174,6 @@
   HasCodec output =>
   -- | Key
   Text ->
-  -- |
   ObjectCodec output output
 requiredField' key = requiredFieldWith' key codec
 
@@ -192,7 +190,6 @@
   Text ->
   -- | Documentation
   Text ->
-  -- |
   ObjectCodec (Maybe output) (Maybe output)
 optionalField key = optionalFieldWith key codec
 
@@ -201,7 +198,6 @@
   HasCodec output =>
   -- | Key
   Text ->
-  -- |
   ObjectCodec (Maybe output) (Maybe output)
 optionalField' key = optionalFieldWith' key codec
 
@@ -220,7 +216,6 @@
   output ->
   -- | Documentation
   Text ->
-  -- |
   ObjectCodec output output
 optionalFieldWithDefault key defaultValue doc = optionalFieldWithDefaultWith key codec defaultValue doc
 
@@ -231,7 +226,6 @@
   Text ->
   -- | Default value
   output ->
-  -- |
   ObjectCodec output output
 optionalFieldWithDefault' key defaultValue = optionalFieldWithDefaultWith' key codec defaultValue
 
diff --git a/src/Autodocodec/Codec.hs b/src/Autodocodec/Codec.hs
--- a/src/Autodocodec/Codec.hs
+++ b/src/Autodocodec/Codec.hs
@@ -67,13 +67,11 @@
 data Codec context input output where
   -- | Encode '()' to the @null@ value, and decode @null@ as '()'.
   NullCodec ::
-    -- |
     ValueCodec () ()
   -- | Encode a 'Bool' to a @boolean@ value, and decode a @boolean@ value as a 'Bool'.
   BoolCodec ::
     -- | Name of the @bool@, for error messages and documentation.
     Maybe Text ->
-    -- |
     JSONCodec Bool
   -- | Encode 'Text' to a @string@ value, and decode a @string@ value as a 'Text'.
   --
@@ -81,7 +79,6 @@
   StringCodec ::
     -- | Name of the @string@, for error messages and documentation.
     Maybe Text ->
-    -- |
     JSONCodec Text
   -- | Encode 'Scientific' to a @number@ value, and decode a @number@ value as a 'Scientific'.
   --
@@ -94,41 +91,31 @@
     Maybe Text ->
     -- | Bounds for the number, these are checked and documented
     Maybe NumberBounds ->
-    -- |
     JSONCodec Scientific
   -- | Encode a 'HashMap', and decode any 'HashMap'.
   HashMapCodec ::
     (Eq k, Hashable k, FromJSONKey k, ToJSONKey k) =>
-    -- |
     JSONCodec v ->
-    -- |
     JSONCodec (HashMap k v)
   -- | Encode a 'Map', and decode any 'Map'.
   MapCodec ::
     (Ord k, FromJSONKey k, ToJSONKey k) =>
-    -- |
     JSONCodec v ->
-    -- |
     JSONCodec (Map k v)
   -- | Encode a 'JSON.Value', and decode any 'JSON.Value'.
   ValueCodec ::
-    -- |
     JSONCodec JSON.Value
   -- | Encode a 'Vector' of values as an @array@ value, and decode an @array@ value as a 'Vector' of values.
   ArrayOfCodec ::
     -- | Name of the @array@, for error messages and documentation.
     Maybe Text ->
-    -- |
     ValueCodec input output ->
-    -- |
     ValueCodec (Vector input) (Vector output)
   -- | Encode a value as a an @object@ value using the given 'ObjectCodec', and decode an @object@ value as a value using the given 'ObjectCodec'.
   ObjectOfCodec ::
     -- | Name of the @object@, for error messages and documentation.
     Maybe Text ->
-    -- |
     ObjectCodec input output ->
-    -- |
     ValueCodec input output
   -- | Match a given value using its 'Eq' instance during decoding, and encode exactly that value during encoding.
   EqCodec ::
@@ -137,7 +124,6 @@
     value ->
     -- | Codec for the value
     JSONCodec value ->
-    -- |
     JSONCodec value
   -- | Map a codec in both directions.
   --
@@ -145,11 +131,8 @@
   -- but we can implement dimap using this function by using a decoding function that does not fail.
   -- Otherwise we would have to have another constructor here.
   BimapCodec ::
-    -- |
     (oldOutput -> Either String newOutput) ->
-    -- |
     (newInput -> oldInput) ->
-    -- |
     Codec context oldInput oldOutput ->
     Codec context newInput newOutput
   -- | Encode/Decode an 'Either' value
@@ -172,7 +155,6 @@
     Codec context input1 output1 ->
     -- | Codec for the 'Right' side
     Codec context input2 output2 ->
-    -- |
     Codec context (Either input1 input2) (Either output1 output2)
   -- | A comment codec
   --
@@ -180,9 +162,7 @@
   CommentCodec ::
     -- | Comment
     Text ->
-    -- |
     ValueCodec input output ->
-    -- |
     ValueCodec input output
   -- | A reference codec
   --
@@ -203,7 +183,6 @@
     ValueCodec input output ->
     -- | Documentation
     Maybe Text ->
-    -- |
     ObjectCodec input output
   OptionalKeyCodec ::
     -- | Key
@@ -212,7 +191,6 @@
     ValueCodec input output ->
     -- | Documentation
     Maybe Text ->
-    -- |
     ObjectCodec (Maybe input) (Maybe output)
   OptionalKeyWithDefaultCodec ::
     -- | Key
@@ -223,7 +201,6 @@
     value ->
     -- | Documentation
     Maybe Text ->
-    -- |
     ObjectCodec value value
   OptionalKeyWithOmittedDefaultCodec ::
     Eq value =>
@@ -235,13 +212,11 @@
     value ->
     -- | Documentation
     Maybe Text ->
-    -- |
     ObjectCodec value value
   -- | To implement 'pure' from 'Applicative'.
   --
   -- Pure is not available for non-object codecs because there is no 'mempty' for 'JSON.Value', which we would need during encoding.
   PureCodec ::
-    -- |
     output ->
     -- |
     --
@@ -251,11 +226,8 @@
   --
   -- Ap is not available for non-object codecs because we cannot combine ('mappend') two encoded 'JSON.Value's
   ApCodec ::
-    -- |
     ObjectCodec input (output -> newOutput) ->
-    -- |
     ObjectCodec input output ->
-    -- |
     ObjectCodec input newOutput
 
 data NumberBounds = NumberBounds
@@ -334,8 +306,6 @@
       ValueCodec -> pure $ showString "ValueCodec"
       MapCodec c -> (\s -> showParen (d > 10) $ showString "MapCodec" . s) <$> go 11 c
       HashMapCodec c -> (\s -> showParen (d > 10) $ showString "HashMapCodec" . s) <$> go 11 c
-#if MIN_VERSION_aeson(2,0,0)
-#endif
       EqCodec value c -> (\s -> showParen (d > 10) $ showString "EqCodec " . showsPrec 11 value . showString " " . s) <$> go 11 c
       BimapCodec _ _ c -> (\s -> showParen (d > 10) $ showString "BimapCodec _ _ " . s) <$> go 11 c
       EitherCodec u c1 c2 -> (\s1 s2 -> showParen (d > 10) $ showString "EitherCodec " . showsPrec 11 u . showString " " . s1 . showString " " . s2) <$> go 11 c1 <*> go 11 c2
@@ -523,11 +493,8 @@
 --
 -- > eitherCodec = possiblyJointEitherCodec
 eitherCodec ::
-  -- |
   Codec context input1 output1 ->
-  -- |
   Codec context input2 output2 ->
-  -- |
   Codec context (Either input1 input2) (Either output1 output2)
 eitherCodec = possiblyJointEitherCodec
 
@@ -602,11 +569,8 @@
 --
 -- > disjointEitherCodec = EitherCodec DisjointUnion
 disjointEitherCodec ::
-  -- |
   Codec context input1 output1 ->
-  -- |
   Codec context input2 output2 ->
-  -- |
   Codec context (Either input1 input2) (Either output1 output2)
 disjointEitherCodec = EitherCodec DisjointUnion
 
@@ -674,11 +638,8 @@
 --
 -- > possiblyJointEitherCodec = EitherCodec PossiblyJointUnion
 possiblyJointEitherCodec ::
-  -- |
   Codec context input1 output1 ->
-  -- |
   Codec context input2 output2 ->
-  -- |
   Codec context (Either input1 input2) (Either output1 output2)
 possiblyJointEitherCodec = EitherCodec PossiblyJointUnion
 
@@ -1042,9 +1003,7 @@
 -- > hashMapCodec = HashMapCodec
 hashMapCodec ::
   (Eq k, Hashable k, FromJSONKey k, ToJSONKey k) =>
-  -- |
   JSONCodec v ->
-  -- |
   JSONCodec (HashMap k v)
 hashMapCodec = HashMapCodec
 
@@ -1058,9 +1017,7 @@
 -- > mapCodec = MapCodec
 mapCodec ::
   (Ord k, FromJSONKey k, ToJSONKey k) =>
-  -- |
   JSONCodec v ->
-  -- |
   JSONCodec (Map k v)
 mapCodec = MapCodec
 
@@ -1178,10 +1135,10 @@
 --
 -- === Example usage
 --
--- > scientificCodec = NumberCodec Nothing Nothing
---
 -- >>> toJSONVia scientificCodec 5
 -- Number 5.0
+-- >>> JSON.parseMaybe scientificCodec (Number 3)
+-- Just 3
 --
 --
 -- === WARNING
@@ -1204,6 +1161,42 @@
 scientificCodec :: JSONCodec Scientific
 scientificCodec = NumberCodec Nothing Nothing
 
+-- | Codec for 'Scientific' values with bounds
+--
+--
+-- === Example usage
+--
+-- >>> let c = scientificWithBoundsCodec NumberBounds {numberBoundsLower = 2, numberBoundsUpper = 4}
+-- >>> toJSONVia c 3
+-- Number 3.0
+-- >>> toJSONVia c 5
+-- Number 5.0
+-- >>> JSON.parseMaybe (parseJSONVia c) (Number 3)
+-- Just 3
+-- >>> JSON.parseMaybe (parseJSONVia c) (Number 5)
+-- Nothing
+--
+--
+-- === WARNING
+--
+-- 'Scientific' is a type that is only for JSON parsing and rendering.
+-- Do not use it for any calculations.
+-- Instead, convert to another number type before doing any calculations.
+--
+-- @
+-- λ> (1 / 3) :: Scientific
+-- *** Exception: fromRational has been applied to a repeating decimal which can't be represented as a Scientific! It's better to avoid performing fractional operations on Scientifics and convert them to other fractional types like Double as early as possible.
+-- @
+--
+--
+-- ==== API Note
+--
+-- This is a forward-compatible version of 'NumberCodec' without a name.
+--
+-- > scientificWithBoundsCodec bounds = NumberCodec Nothing (Just bounds)
+scientificWithBoundsCodec :: NumberBounds -> JSONCodec Scientific
+scientificWithBoundsCodec bounds = NumberCodec Nothing (Just bounds)
+
 -- | An object codec with a given name
 --
 --
@@ -1243,11 +1236,7 @@
 -- Nothing
 boundedIntegralCodec :: forall i. (Integral i, Bounded i) => JSONCodec i
 boundedIntegralCodec =
-  bimapCodec go fromIntegral $
-    NumberCodec
-      Nothing
-      ( Just (boundedIntegralNumberBounds @i)
-      )
+  bimapCodec go fromIntegral $ scientificWithBoundsCodec (boundedIntegralNumberBounds @i)
   where
     go s = case Scientific.toBoundedInteger s of
       Nothing -> Left $ "Number did not fit into bounded integer: " <> show s
@@ -1347,7 +1336,6 @@
   Codec context input' output ->
   -- | Rendering chooser
   (newInput -> Either input input') ->
-  -- |
   Codec context newInput output
 matchChoiceCodec = matchChoiceCodecAs PossiblyJointUnion
 
@@ -1366,7 +1354,6 @@
   Codec context input' output ->
   -- | Rendering chooser
   (newInput -> Either input input') ->
-  -- |
   Codec context newInput output
 disjointMatchChoiceCodec = matchChoiceCodecAs DisjointUnion
 
@@ -1380,7 +1367,6 @@
   Codec context input' output ->
   -- | Rendering chooser
   (newInput -> Either input input') ->
-  -- |
   Codec context newInput output
 matchChoiceCodecAs union c1 c2 renderingChooser =
   dimapCodec (either id id) renderingChooser $
@@ -1429,7 +1415,6 @@
   [(input -> Maybe input, Codec context input output)] ->
   -- | Fallback codec, in case none of the matchers in the list match
   Codec context input output ->
-  -- |
   Codec context input output
 matchChoicesCodec = matchChoicesCodecAs PossiblyJointUnion
 
@@ -1446,7 +1431,6 @@
   [(input -> Maybe input, Codec context input output)] ->
   -- | Fallback codec, in case none of the matchers in the list match
   Codec context input output ->
-  -- |
   Codec context input output
 disjointMatchChoicesCodec = matchChoicesCodecAs DisjointUnion
 
@@ -1457,7 +1441,6 @@
   [(input -> Maybe input, Codec context input output)] ->
   -- | Fallback codec, in case none of the matchers in the list match
   Codec context input output ->
-  -- |
   Codec context input output
 matchChoicesCodecAs union l fallback = go l
   where
@@ -1527,9 +1510,7 @@
 enumCodec ::
   forall enum context.
   Eq enum =>
-  -- |
   NonEmpty (enum, Codec context enum enum) ->
-  -- |
   Codec context enum enum
 enumCodec = go
   where
@@ -1564,9 +1545,7 @@
 stringConstCodec ::
   forall constant.
   Eq constant =>
-  -- |
   NonEmpty (constant, Text) ->
-  -- |
   JSONCodec constant
 stringConstCodec =
   enumCodec
@@ -1591,7 +1570,6 @@
 shownBoundedEnumCodec ::
   forall enum.
   (Show enum, Eq enum, Enum enum, Bounded enum) =>
-  -- |
   JSONCodec enum
 shownBoundedEnumCodec =
   let ls = [minBound .. maxBound]
