diff --git a/ChangeLog.md b/ChangeLog.md
--- a/ChangeLog.md
+++ b/ChangeLog.md
@@ -1,4 +1,31 @@
-See also http://pvp.haskell.org/faq
+## 0.95.0.1
+
+_2025-03-02 Andreas Abel_
+
+- Drop support for GHC 7
+- Make `Prelude` imports explicit, add `LANGUAGE NoImplicitPrelude`
+- Make upper bounds of dependencies major-major (all are shipped with GHC)
+- Tested with GHC 8.0 - 9.12.1
+
+## 0.95.0.0 revision 6
+
+- Allow `containers-0.7`
+
+## 0.95.0.0 revision 5
+
+- Allow `bytestring-0.12`
+
+## 0.95.0.0 revision 4
+
+- Compatibility with `base >= 4.17` (GHC 9.4)
+
+## 0.95.0.0 revision 3
+
+- Compatibility with `base-4.16` (GHC 9.2)
+
+## 0.95.0.0 revision 2
+
+- Compatibility with `base-4.15` (GHC 9.0) and `bytestring-0.11`
 
 ## 0.95.0.0
 
diff --git a/LICENSE b/LICENSE
--- a/LICENSE
+++ b/LICENSE
@@ -10,6 +10,3 @@
     * The names of the contributors may not be used to endorse or promote products derived from this software without specific prior written permission.
 
 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-
-
diff --git a/README.md b/README.md
new file mode 100644
--- /dev/null
+++ b/README.md
@@ -0,0 +1,13 @@
+[![Hackage version](https://img.shields.io/hackage/v/regex-pcre.svg?label=Hackage&color=informational)](http://hackage.haskell.org/package/regex-pcre)
+[![Stackage Nightly](http://stackage.org/package/regex-pcre/badge/nightly)](http://stackage.org/nightly/package/regex-pcre)
+[![Stackage LTS](http://stackage.org/package/regex-pcre/badge/lts)](http://stackage.org/lts/package/regex-pcre)
+[![Haskell-CI](https://github.com/haskell-hvr/regex-pcre/actions/workflows/haskell-ci.yml/badge.svg?branch=master&event=push)](https://github.com/haskell-hvr/regex-pcre/actions/workflows/haskell-ci.yml)
+[![License](https://img.shields.io/badge/License-BSD_3--Clause-blue.svg)](https://opensource.org/licenses/BSD-3-Clause)
+regex-pcre
+==========
+
+Backend for `regex-base` via binding to PCRE library.
+
+[Documentation](https://hackage.haskell.org/package/regex-pcre/docs/Text-Regex-PCRE.html) on hackage.
+
+Binding to PCRE2 is in [`regex-pcre2`](https://hackage.haskell.org/package/regex-pcre2).
diff --git a/Setup.hs b/Setup.hs
deleted file mode 100644
--- a/Setup.hs
+++ /dev/null
@@ -1,2 +0,0 @@
-import Distribution.Simple                                           
-main = defaultMain
diff --git a/regex-pcre.cabal b/regex-pcre.cabal
--- a/regex-pcre.cabal
+++ b/regex-pcre.cabal
@@ -1,14 +1,15 @@
-Cabal-Version:          1.12
+Cabal-Version:          1.24
 Name:                   regex-pcre
-Version:                0.95.0.0
+Version:                0.95.0.1
 
 build-type:             Simple
 license:                BSD3
 license-file:           LICENSE
 copyright:              Copyright (c) 2006, Christopher Kuklewicz
 author:                 Christopher Kuklewicz
-maintainer:             hvr@gnu.org
-bug-reports:            https://github.com/hvr/regex-pcre/issues
+maintainer:             Andreas Abel
+homepage:               https://wiki.haskell.org/Regular_expressions
+bug-reports:            https://github.com/haskell-hvr/regex-pcre/issues
 category:               Text
 
 synopsis:    PCRE Backend for "Text.Regex" (regex-base)
@@ -17,18 +18,39 @@
   .
   See also <https://wiki.haskell.org/Regular_expressions> for more information.
 
-extra-source-files:
+extra-doc-files:
   ChangeLog.md
+  README.md
 
+tested-with:
+  GHC == 9.12.1
+  GHC == 9.10.1
+  GHC == 9.8.4
+  GHC == 9.6.6
+  GHC == 9.4.8
+  GHC == 9.2.8
+  GHC == 9.0.2
+  GHC == 8.10.7
+  GHC == 8.8.4
+  GHC == 8.6.5
+  GHC == 8.4.4
+  GHC == 8.2.2
+  GHC == 8.0.2
+
 flag pkg-config
   default:     True
   manual:      True
-  description: Use @pkg-config(1)@ to locate foreign @zlib@ library.
+  description: Use @pkg-config(1)@ to locate foreign @pcre@ library.
 
 source-repository head
   type:     git
-  location: https://github.com/hvr/regex-pcre.git
+  location: https://github.com/haskell-hvr/regex-pcre.git
 
+source-repository this
+  type:     git
+  location: https://github.com/haskell-hvr/regex-pcre.git
+  tag:      v0.95.0.1
+
 library
   hs-source-dirs: src
   exposed-modules:
@@ -42,8 +64,10 @@
   other-modules:
       Paths_regex_pcre
 
-  default-language: Haskell2010
+  default-language:
+      Haskell2010
   default-extensions:
+      NoImplicitPrelude
       MultiParamTypeClasses
       FunctionalDependencies
       ForeignFunctionInterface
@@ -53,19 +77,18 @@
       TypeSynonymInstances
       FlexibleInstances
 
-  build-depends: regex-base == 0.94.*
-               , base       >= 4.3 && < 4.14
-               , containers >= 0.4 && < 0.7
-               , bytestring >= 0.9 && < 0.11
-               , array      >= 0.3 && < 0.6
-
-  if !impl(ghc >= 8)
-      build-depends: fail == 4.9.*
+  build-depends:
+        regex-base == 0.94.*
+      , base       >= 4.9  && < 5
+      , containers >= 0.5  && < 1
+      , bytestring >= 0.10 && < 1
+      , array      >= 0.5  && < 1
 
   if flag(pkg-config)
     pkgconfig-depends: libpcre
   else
     extra-libraries: pcre
 
-  ghc-options: -O2
-               -Wall -fno-warn-unused-imports
+  ghc-options:
+    -Wall
+    -Wcompat
diff --git a/src/Text/Regex/PCRE.hs b/src/Text/Regex/PCRE.hs
--- a/src/Text/Regex/PCRE.hs
+++ b/src/Text/Regex/PCRE.hs
@@ -30,7 +30,7 @@
   -- ** Wrap, for '=~' and '=~~', types and constants
   ,module Text.Regex.PCRE.Wrap) where
 
-import Prelude hiding (fail)
+import Prelude ()
 
 import Text.Regex.PCRE.Wrap(Regex, CompOption(CompOption), ExecOption(ExecOption), (=~), (=~~),
   unusedOffset, getNumSubs, configUTF8, getVersion,
@@ -44,7 +44,7 @@
 import Text.Regex.PCRE.Sequence()
 import Text.Regex.PCRE.ByteString()
 import Text.Regex.PCRE.ByteString.Lazy()
-import Data.Version(Version(..))
+import Data.Version(Version)
 import Text.Regex.Base
 import qualified Paths_regex_pcre
 
diff --git a/src/Text/Regex/PCRE/ByteString.hs b/src/Text/Regex/PCRE/ByteString.hs
--- a/src/Text/Regex/PCRE/ByteString.hs
+++ b/src/Text/Regex/PCRE/ByteString.hs
@@ -1,4 +1,4 @@
-{-# OPTIONS_GHC -fno-warn-orphans #-}
+{-# OPTIONS_GHC -Wno-orphans #-}
 {-|
 This exports instances of the high level API and the medium level
 API of 'compile','execute', and 'regexec'.
@@ -45,7 +45,16 @@
   execPartial
   ) where
 
-import Prelude hiding (fail)
+import Prelude
+  ( Either(Left,Right), either
+  , Int, (-), fromIntegral, pred
+  , IO, (>>=), return
+  , Maybe(Nothing,Just)
+  , Show(show)
+  , String
+  , ($), (.), (==), (&&), otherwise, not
+  , (++), map, length
+  )
 import Control.Monad.Fail (MonadFail(fail))
 
 import Text.Regex.PCRE.Wrap -- all
diff --git a/src/Text/Regex/PCRE/ByteString/Lazy.hs b/src/Text/Regex/PCRE/ByteString/Lazy.hs
--- a/src/Text/Regex/PCRE/ByteString/Lazy.hs
+++ b/src/Text/Regex/PCRE/ByteString/Lazy.hs
@@ -1,4 +1,5 @@
-{-# OPTIONS_GHC -fno-warn-orphans #-}
+{-# OPTIONS_GHC -Wno-orphans #-}
+
 {-|
 This exports instances of the high level API and the medium level
 API of 'compile','execute', and 'regexec'.
@@ -45,7 +46,16 @@
   execPartial
   ) where
 
-import Prelude hiding (fail)
+import Prelude
+  ( Either(Left,Right), either
+  , Int
+  , IO, (>>=), return
+  , Maybe(Nothing,Just)
+  , Show(show)
+  , String
+  , ($), (.), (==), (&&), otherwise, not
+  , (++), map
+  )
 import Control.Monad.Fail (MonadFail(fail))
 
 import Text.Regex.PCRE.Wrap -- all
diff --git a/src/Text/Regex/PCRE/Sequence.hs b/src/Text/Regex/PCRE/Sequence.hs
--- a/src/Text/Regex/PCRE/Sequence.hs
+++ b/src/Text/Regex/PCRE/Sequence.hs
@@ -45,7 +45,19 @@
   execPartial
   ) where
 
-import Prelude hiding (fail)
+import Prelude
+  ( Bool(False)
+  , Char
+  , Either(Left,Right), either
+  , IO, (>>), (>>=), return
+  , Int, (-), fromIntegral, pred
+  , Maybe(Nothing,Just)
+  , Show(show)
+  , String
+  , ($), (.), seq, undefined
+  , (==), otherwise
+  , (++), length, map
+  )
 import Control.Monad.Fail (MonadFail(fail))
 
 import Text.Regex.PCRE.Wrap -- all
@@ -54,12 +66,20 @@
 import System.IO.Unsafe(unsafePerformIO)
 import Text.Regex.Base.RegexLike(RegexMaker(..),RegexLike(..),RegexContext(..),MatchLength,MatchOffset,Extract(..))
 import Text.Regex.Base.Impl(polymatch,polymatchM)
-import Data.Sequence as S hiding (length)
+import Data.Sequence as S
+    ( Seq,
+      empty,
+      singleton,
+      viewl,
+      viewr,
+      (|>),
+      ViewL((:<), EmptyL),
+      ViewR((:>), EmptyR) )
 import qualified Data.Sequence as S (length)
-import Foreign.C.String
-import Foreign.Marshal.Array
-import Foreign.Marshal.Alloc
-import Foreign.Storable
+import Foreign.C.String ( castCharToCChar, CString, CStringLen )
+import Foreign.Marshal.Array ( advancePtr )
+import Foreign.Marshal.Alloc ( allocaBytes )
+import Foreign.Storable ( Storable(poke) )
 
 instance RegexContext Regex (Seq Char) (Seq Char) where
   match = polymatch
@@ -80,9 +100,9 @@
     withSeq str (wrapTest 0 regex) >>= unwrap
   matchOnce regex str = unsafePerformIO $
     execute regex str >>= unwrap
-  matchAll regex str = unsafePerformIO $ 
+  matchAll regex str = unsafePerformIO $
     withSeq str (wrapMatchAll regex) >>= unwrap
-  matchCount regex str = unsafePerformIO $ 
+  matchCount regex str = unsafePerformIO $
     withSeq str (wrapCount regex) >>= unwrap
 
 -- | Compiles a regular expression
@@ -104,7 +124,7 @@
   case maybeStartEnd of
     Right Nothing -> return (Right Nothing)
 --  Right (Just []) -> fail "got [] back!" -- should never happen
-    Right (Just parts) -> 
+    Right (Just parts) ->
       return . Right . Just . listArray (0,pred (length parts))
       . map (\(s,e)->(fromIntegral s, fromIntegral (e-s))) $ parts
     Left err -> return (Left err)
@@ -119,7 +139,7 @@
   let getSub (start,stop) | start == unusedOffset = S.empty
                           | otherwise = extract (start,stop-start) str
       matchedParts [] = (S.empty,S.empty,str,[]) -- no information
-      matchedParts (matchedStartStop@(start,stop):subStartStop) = 
+      matchedParts (matchedStartStop@(start,stop):subStartStop) =
         (before start str
         ,getSub matchedStartStop
         ,after stop str
diff --git a/src/Text/Regex/PCRE/String.hs b/src/Text/Regex/PCRE/String.hs
--- a/src/Text/Regex/PCRE/String.hs
+++ b/src/Text/Regex/PCRE/String.hs
@@ -45,7 +45,16 @@
   execPartial
   ) where
 
-import Prelude hiding (fail)
+import Prelude
+  ( Either(Left,Right), either
+  , Int, (-), fromIntegral, pred
+  , IO, (>>=), return
+  , Maybe(Nothing,Just)
+  , Show(show)
+  , String
+  , ($), (.), (==), otherwise
+  , (++), drop, length, map, take
+  )
 import Control.Monad.Fail (MonadFail(fail))
 
 import Text.Regex.PCRE.Wrap -- all
@@ -74,9 +83,9 @@
     withCStringLen str (wrapTest 0 regex) >>= unwrap
   matchOnce regex str = unsafePerformIO $
     execute regex str >>= unwrap
-  matchAll regex str = unsafePerformIO $ 
+  matchAll regex str = unsafePerformIO $
     withCStringLen str (wrapMatchAll regex) >>= unwrap
-  matchCount regex str = unsafePerformIO $ 
+  matchCount regex str = unsafePerformIO $
     withCStringLen str (wrapCount regex) >>= unwrap
 
 -- | Compiles a regular expression
@@ -98,7 +107,7 @@
   case maybeStartEnd of
     Right Nothing -> return (Right Nothing)
 --  Right (Just []) -> fail "got [] back!" -- should never happen
-    Right (Just parts) -> 
+    Right (Just parts) ->
       return . Right . Just . listArray (0,pred (length parts))
       . map (\(s,e)->(fromIntegral s, fromIntegral (e-s))) $ parts
     Left err -> return (Left err)
@@ -113,7 +122,7 @@
   let getSub (start,stop) | start == unusedOffset = ""
                           | otherwise = take (stop-start) . drop start $ str
       matchedParts [] = ("","",str,[]) -- no information
-      matchedParts (matchedStartStop@(start,stop):subStartStop) = 
+      matchedParts (matchedStartStop@(start,stop):subStartStop) =
         (take start str
         ,getSub matchedStartStop
         ,drop stop str
diff --git a/src/Text/Regex/PCRE/Wrap.hsc b/src/Text/Regex/PCRE/Wrap.hsc
--- a/src/Text/Regex/PCRE/Wrap.hsc
+++ b/src/Text/Regex/PCRE/Wrap.hsc
@@ -69,23 +69,31 @@
   retNoSubstring
   ) where
 
-import Prelude hiding (fail)
+import Prelude
+  ( Bool(False,True)
+  , Either(Left,Right)
+  , Eq, (==), (/=), (<)
+  , IO, (=<<), return
+  , Integral, Int, (*), (-), fromIntegral, succ
+  , Maybe(Nothing,Just)
+  , Num((+))
+  , Show(show)
+  , String
+  , ($), (.), id, error, seq, undefined, otherwise
+  , (++), mapM, replicate, zip
+  )
 import Control.Monad.Fail (MonadFail(fail))
 
 import Control.Monad(when)
 import Data.Array(Array,accumArray)
-import Data.Bits(Bits((.|.))) -- ((.&.),(.|.),complement))
+import Data.Bits(Bits((.|.)))
 import System.IO.Unsafe(unsafePerformIO)
-import Foreign(Ptr,ForeignPtr,FinalizerPtr -- ,FunPtr
+import Foreign(Ptr,ForeignPtr,FinalizerPtr
               ,alloca,allocaBytes,nullPtr
               ,peek,peekElemOff
               ,newForeignPtr,withForeignPtr)
 import Foreign.C(CChar)
-#if __GLASGOW_HASKELL__ >= 703
 import Foreign.C(CInt(CInt))
-#else
-import Foreign.C(CInt)
-#endif
 import Foreign.C.String(CString,CStringLen,peekCString)
 import Text.Regex.Base.RegexLike(RegexOptions(..),RegexMaker(..),RegexContext(..),MatchArray,MatchOffset)
 
@@ -181,14 +189,14 @@
 {-# INLINE nullTest' #-}
 nullTest' ptr msg io = do
   if nullPtr == ptr
-    then return (Left (0,"Ptr parameter was nullPtr in Text.Regex.PCRE.Wrap."++msg)) 
+    then return (Left (0,"Ptr parameter was nullPtr in Text.Regex.PCRE.Wrap."++msg))
     else io
 
 nullTest :: Ptr a -> String -> IO (Either WrapError b) -> IO (Either WrapError b)
 {-# INLINE nullTest #-}
 nullTest ptr msg io = do
   if nullPtr == ptr
-    then return (Left (retOk,"Ptr parameter was nullPtr in Text.Regex.PCRE.Wrap."++msg)) 
+    then return (Left (retOk,"Ptr parameter was nullPtr in Text.Regex.PCRE.Wrap."++msg))
     else io
 
 wrapRC :: ReturnCode -> IO (Either WrapError b)
@@ -264,8 +272,8 @@
 
 -- | wrapMatchAll is an improvement over wrapMatch since it only
 -- allocates memory with allocaBytes once at the start.
--- 
--- 
+--
+--
 wrapMatchAll (Regex pcre_fptr _ flags) (cstr,len) = do
  nullTest cstr "wrapMatchAll cstr" $ do
   withForeignPtr pcre_fptr $ \regex -> do
@@ -292,7 +300,7 @@
                        let acc' = acc . (toMatchArray nsub_int pairs:)
                        case pairs of
                          [] -> return (Right (acc' []))
-                         ((s,e):_) | s==e -> if s == len 
+                         ((s,e):_) | s==e -> if s == len
                                                then return (Right (acc' []))
                                                else loop acc' flags' e
                                    | otherwise -> loop acc' flags e
