diff --git a/bench/Bench.hs b/bench/Bench.hs
--- a/bench/Bench.hs
+++ b/bench/Bench.hs
@@ -12,7 +12,6 @@
 import qualified Parsec
 import qualified FPStateful
 import qualified FPBasic
--- import qualified Bytesmith
 import qualified ReadInteger
 
 sexpInp :: B.ByteString
@@ -25,15 +24,6 @@
 numcsvInp :: B.ByteString
 numcsvInp = B.concat ("0" : [B.pack (",  " ++ show n) | n <- [1..100000::Int]])
 
--- sexpInp' :: ByteArray
--- sexpInp' = Bytesmith.strToByteArray $ B.unpack sexpInp
-
--- longwsInp' :: ByteArray
--- longwsInp' = Bytesmith.strToByteArray $ B.unpack longwsInp
-
--- numcsvInp' :: ByteArray
--- numcsvInp' = Bytesmith.strToByteArray $ B.unpack numcsvInp
-
 readIntInp :: B.ByteString
 readIntInp = "12345678910"
 
@@ -42,7 +32,6 @@
   bgroup "sexp" [
     bench "fpbasic"     $ whnf FPBasic.runSexp    sexpInp,
     bench "fpstateful"  $ whnf FPStateful.runSexp sexpInp,
-    -- bench "bytesmith"   $ whnf Bytesmith.runSexp  sexpInp',
     bench "attoparsec"  $ whnf Attoparsec.runSexp sexpInp,
     bench "megaparsec"  $ whnf Megaparsec.runSexp sexpInp,
     bench "parsec"      $ whnf Parsec.runSexp     sexpInp
@@ -51,7 +40,6 @@
   bgroup "long keyword" [
     bench "fpbasic"    $ whnf FPBasic.runLongws    longwsInp,
     bench "fpstateful" $ whnf FPStateful.runLongws longwsInp,
-    -- bench "bytesmith"  $ whnf Bytesmith.runLongws  longwsInp',
     bench "attoparsec" $ whnf Attoparsec.runLongws longwsInp,
     bench "megaparsec" $ whnf Megaparsec.runLongws longwsInp,
     bench "parsec"     $ whnf Parsec.runLongws     longwsInp
@@ -60,7 +48,6 @@
   bgroup "numeral csv" [
     bench "fpbasic"    $ whnf FPBasic.runNumcsv    numcsvInp,
     bench "fpstateful" $ whnf FPStateful.runNumcsv numcsvInp,
-    -- bench "bytesmith"  $ whnf Bytesmith.runNumcsv  numcsvInp',
     bench "attoparsec" $ whnf Attoparsec.runNumcsv numcsvInp,
     bench "megaparsec" $ whnf Megaparsec.runNumcsv numcsvInp,
     bench "parsec"     $ whnf Parsec.runNumcsv     numcsvInp
diff --git a/bench/Bytesmith.hs b/bench/Bytesmith.hs
deleted file mode 100644
--- a/bench/Bytesmith.hs
+++ /dev/null
@@ -1,65 +0,0 @@
-{-# language RankNTypes #-}
-
-module Bytesmith where
-
--- module Bytesmith (runSexp, runLongws, runNumcsv, strToByteArray) where
-
--- import Control.Applicative
-
--- import GHC.Exts
-
--- import qualified Data.Bytes.Parser       as P
--- import qualified Data.Bytes.Parser.Ascii as A
-
--- import Data.Primitive.ByteArray
--- import Data.Char
-
--- strToByteArray :: String -> ByteArray
--- strToByteArray = fromList . map (fromIntegral . ord)
-
--- byteArrayToStr :: ByteArray -> String
--- byteArrayToStr = map (chr . fromIntegral) . toList
-
--- parseByteArray :: (forall s. Parser s) -> ByteArray -> Bool
--- parseByteArray p b = case P.parseByteArray p b of
---   P.Failure{} -> False
---   _           -> True
--- {-# inline parseByteArray #-}
-
--- data U = U
--- instance Semigroup U where (<>) _ _ = U
--- instance Monoid U    where mempty   = U
-
--- type Parser s = P.Parser U s ()
-
--- many_ :: Parser s -> Parser s
--- many_ p = go where
---   go = (p >> go) <|> pure ()
--- {-# inline many_ #-}
-
--- some_ :: Parser s -> Parser s
--- some_ p = p >> many_ p
--- {-# inline some_ #-}
-
--- ws :: Parser s
--- ws = many_ do
---   P.any U >>= \case
---     32 -> pure ()      -- ' '
---     10 -> pure ()      -- '\n'
---     _  -> P.fail U
-
--- open    = A.char U '(' >> ws
--- close   = A.char U ')' >> ws
--- ident   = A.skipAlpha1 U >> ws
--- sexp    = (open >> some_ sexp >> close) <|> ident
--- src     = sexp >> P.endOfInput U
--- runSexp = parseByteArray src
-
--- longw     = P.cstring U (Ptr "thisisalongkeyword\NUL"#)
--- longws    = some_ (longw >> ws) >> P.endOfInput U
--- runLongws = parseByteArray longws
-
--- numeral   = A.skipDigits1 U >> ws
--- comma     = A.char U ',' >> ws
--- numcsv    = numeral >> many_ (comma >> numeral) >> P.endOfInput U
--- runNumcsv = parseByteArray numcsv
diff --git a/flatparse.cabal b/flatparse.cabal
--- a/flatparse.cabal
+++ b/flatparse.cabal
@@ -5,7 +5,7 @@
 -- see: https://github.com/sol/hpack
 
 name:           flatparse
-version:        0.3.0.0
+version:        0.3.0.1
 synopsis:       High-performance parsing from strict bytestrings
 description:    @Flatparse@ is a high-performance parsing library, focusing on programming languages and
                 human-readable data formats. See the README for more information:
@@ -20,7 +20,10 @@
 license-file:   LICENSE
 build-type:     Simple
 tested-with:
-    GHC == 9.0.1
+    GHC == 8.6.5
+  , GHC == 8.8.4
+  , GHC == 8.10.7
+  , GHC == 9.0.1
 extra-source-files:
     README.md
 
@@ -49,6 +52,7 @@
       PatternSynonyms
       TemplateHaskell
       TupleSections
+      CPP
   ghc-options: -Wall -Wno-name-shadowing -Wno-unused-binds -Wno-unused-matches -Wno-missing-signatures -O2 -fllvm
   build-depends:
       base >=4.7 && <5
@@ -75,6 +79,7 @@
       PatternSynonyms
       TemplateHaskell
       TupleSections
+      CPP
       ExtendedDefaultRules
   ghc-options: -Wall -Wno-name-shadowing -Wno-unused-binds -Wno-unused-matches -Wno-missing-signatures -O2 -fllvm -Wno-type-defaults
   build-depends:
@@ -90,7 +95,6 @@
   main-is: Bench.hs
   other-modules:
       Attoparsec
-      Bytesmith
       FPBasic
       FPStateful
       Megaparsec
@@ -109,6 +113,7 @@
       PatternSynonyms
       TemplateHaskell
       TupleSections
+      CPP
   ghc-options: -Wall -Wno-name-shadowing -Wno-unused-binds -Wno-unused-matches -Wno-missing-signatures -O2 -fllvm
   build-depends:
       attoparsec
diff --git a/src/FlatParse/Basic.hs b/src/FlatParse/Basic.hs
--- a/src/FlatParse/Basic.hs
+++ b/src/FlatParse/Basic.hs
@@ -953,6 +953,14 @@
 -- Switching code generation
 --------------------------------------------------------------------------------
 
+#if MIN_VERSION_base(4,15,0)
+mkDoE = DoE Nothing
+{-# inline mkDoE #-}
+#else
+mkDoE = DoE
+{-# inline mkDoE #-}
+#endif
+
 genTrie :: (Map (Maybe Int) Exp, Trie' (Rule, Int, Maybe Int)) -> Q Exp
 genTrie (rules, t) = do
   branches <- traverse (\e -> (,) <$> (newName "rule") <*> pure e) rules
@@ -976,7 +984,7 @@
               !next         <- (traverse . traverse) go (M.toList ts)
               !defaultCase  <- fallback r (n + 1)
 
-              let cases = DoE Nothing $
+              let cases = mkDoE $
                     [BindS (VarP (mkName "c")) (VarE 'scanAny8#),
                       NoBindS (CaseE (VarE (mkName "c"))
                          (map (\(w, t) ->
diff --git a/src/FlatParse/Internal.hs b/src/FlatParse/Internal.hs
--- a/src/FlatParse/Internal.hs
+++ b/src/FlatParse/Internal.hs
@@ -9,13 +9,30 @@
 import Data.Word
 import GHC.Exts
 import GHC.ForeignPtr
-import GHC.Num.Integer (Integer(..))
 
 import qualified Data.ByteString as B
 import qualified Data.ByteString.Char8 as BC8
 import qualified Data.ByteString.Internal as B
 import qualified Data.Map.Strict as M
 
+#if MIN_VERSION_base(4,15,0)
+import GHC.Num.Integer (Integer(..))
+#else
+import GHC.Integer.GMP.Internals (Integer(..))
+#endif
+
+-- Compatibility
+--------------------------------------------------------------------------------
+
+shortInteger :: Int# -> Integer
+#if MIN_VERSION_base(4,15,0)
+shortInteger = IS
+{-# inline shortInteger #-}
+#else
+shortInteger = S#
+#endif
+
+
 -- Char predicates
 --------------------------------------------------------------------------------
 
@@ -63,7 +80,7 @@
 readInteger fp eob s = case readInt' 0# s eob of
   (# n, s' #)
     | 1# <- eqAddr# s s'            -> (# (##) | #)
-    | 1# <- minusAddr# s' s <=# 18# -> (# | (# IS n, s' #) #)
+    | 1# <- minusAddr# s' s <=# 18# -> (# | (# shortInteger n, s' #) #)
     | otherwise -> case BC8.readInteger (B.PS (ForeignPtr s fp) 0 (I# (minusAddr# s' s))) of
         Nothing     -> (# (##) | #)
         Just (i, _) -> (# | (# i, s' #) #)
diff --git a/src/FlatParse/Stateful.hs b/src/FlatParse/Stateful.hs
--- a/src/FlatParse/Stateful.hs
+++ b/src/FlatParse/Stateful.hs
@@ -933,6 +933,14 @@
 -- Switching code generation
 --------------------------------------------------------------------------------
 
+#if MIN_VERSION_base(4,15,0)
+mkDoE = DoE Nothing
+{-# inline mkDoE #-}
+#else
+mkDoE = DoE
+{-# inline mkDoE #-}
+#endif
+
 genTrie :: (Map (Maybe Int) Exp, Trie' (Rule, Int, Maybe Int)) -> Q Exp
 genTrie (rules, t) = do
   branches <- traverse (\e -> (,) <$> (newName "rule") <*> pure e) rules
@@ -956,7 +964,7 @@
               !next         <- (traverse . traverse) go (M.toList ts)
               !defaultCase  <- fallback r (n + 1)
 
-              let cases = DoE Nothing $
+              let cases = mkDoE $
                     [BindS (VarP (mkName "c")) (VarE 'scanAny8#),
                       NoBindS (CaseE (VarE (mkName "c"))
                          (map (\(w, t) ->
