diff --git a/CHANGELOG.md b/CHANGELOG.md
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -5,6 +5,20 @@
 The format is based on [Keep a Changelog](http://keepachangelog.com/)
 and this project adheres to the [Haskell Package Versioning Policy](https://pvp.haskell.org/).
 
+## [1.1.7] - 2021-05-12
+
+### Changed
+- Support hspec-2.8.0
+
+### Removed
+- Don't re-export `Test.Hspec`
+- Drop support for hspec < 2.5
+
+## [1.1.6-r1] - 2021-03-13
+
+### Changed
+- Support base-4.15
+
 ## [1.1.6] - 2020-11-11
 
 ### Changed
diff --git a/src/Test/Tasty/Hspec.hs b/src/Test/Tasty/Hspec.hs
--- a/src/Test/Tasty/Hspec.hs
+++ b/src/Test/Tasty/Hspec.hs
@@ -1,44 +1,38 @@
-{-# LANGUAGE CPP                #-}
-{-# LANGUAGE DeriveDataTypeable #-}
+{-# LANGUAGE CPP #-}
 
 -- | @hspec@ and @tasty@ serve similar purposes; consider using one or the
 -- other.
 --
 -- However, in a pinch, this module allows you to run an @hspec@ 'H.Spec' as a
 -- @tasty@ 'T.TestTree'.
-
 module Test.Tasty.Hspec
-    ( -- * Tests
-      testSpec
-    , testSpecs
+  ( -- * Tests
+    testSpec,
+    testSpecs,
+
     -- * Options
-    , TreatPendingAs(..)
-    -- * Re-exports
-    , module Test.Hspec
-      -- * Examples
-      -- $examples
-    ) where
+    TreatPendingAs (..),
 
+    -- * Examples
+    -- $examples
+  )
+where
+
 import Control.Applicative ((<$>))
-import Control.Exception (SomeException)
 import Control.Monad (guard)
 import Data.Maybe (catMaybes, fromMaybe, mapMaybe)
 import Data.Proxy
 import Data.Typeable (Typeable)
-
 import qualified Test.Hspec as H
 import qualified Test.Hspec.Core.Formatters as H
 import qualified Test.Hspec.Core.Spec as H
-import qualified Test.QuickCheck as QC
 import qualified Test.Tasty as T
-import qualified Test.Tasty.SmallCheck as TSC
+import Test.Tasty.Hspec.Compat
 import qualified Test.Tasty.Options as T
 import qualified Test.Tasty.Providers as T
 import qualified Test.Tasty.QuickCheck as TQC
 import qualified Test.Tasty.Runners as T
-
--- For re-export.
-import Test.Hspec
+import qualified Test.Tasty.SmallCheck as TSC
 
 -- $examples
 --
@@ -62,9 +56,9 @@
 -- tests :: TestTree
 -- tests =
 --   localOption TreatPendingAsSuccess $ testGroup "My Hspec TestTree"
---     $ [ unsafePerformIO (testSpec "My first Hspec test" spec_firstHspecTest)
---       , ...
---       ]
+--     [ unsafePerformIO (testSpec "My first Hspec test" spec_firstHspecTest)
+--     , ...
+--     ]
 -- @
 --
 -- However, if you don't do any @IO@ during 'Spec' creation, or the @IO@ need
@@ -83,194 +77,87 @@
 -- | Create a <https://hackage.haskell.org/package/tasty tasty> 'T.TestTree' from an
 -- <https://hackage.haskell.org/package/hspec Hspec> 'H.Spec'.
 testSpec :: T.TestName -> H.Spec -> IO T.TestTree
-testSpec name spec = T.testGroup name <$> testSpecs spec
+testSpec name spec = do
+  trees <- testSpecs spec
+  pure (T.testGroup name trees)
 
--- | Create a list of <https://hackage.haskell.org/package/tasty tasty>
--- 'T.TestTree' from an <https://hackage.haskell.org/package/hspec Hspec>
--- 'H.Spec'. This returns the same tests as 'testSpec' but doesn't create
--- a <https://hackage.haskell.org/package/tasty tasty> test group from them.
+-- | Create a list of <https://hackage.haskell.org/package/tasty tasty> 'T.TestTree' from an
+-- <https://hackage.haskell.org/package/hspec Hspec> 'H.Spec'. This returns the same tests as 'testSpec'
+-- but doesn't create a <https://hackage.haskell.org/package/tasty tasty> test group from them.
 testSpecs :: H.Spec -> IO [T.TestTree]
-testSpecs spec =
-  catMaybes . map specTreeToTestTree <$>
-    -- In hspec 2.6.0, "focus" was introduced. Here we do as hspec does, which
-    -- is pre-process a spec by focusing the whole thing, which is a no-op if
-    -- anything inside is already focused, but otherwise focuses every item.
-    -- Then, when creating a tasty test tree, we just toss the unfocused items.
-    H.runSpecM (doFocus spec)
-  where
-    doFocus :: H.Spec -> H.Spec
-    doFocus =
-#if MIN_VERSION_hspec(2,6,0)
-      H.focus
-#else
-      id
-#endif
+testSpecs spec = do
+  -- Here we do as hspec does, which is pre-process a spec by focusing the whole thing, which is a no-op if
+  -- anything inside is already focused, but otherwise focuses every item. Then, when creating a tasty test tree,
+  -- we just toss the unfocused items.
+  trees <- H.runSpecM (focus spec)
+  pure (mapMaybe specTreeToTestTree trees)
 
 specTreeToTestTree :: H.SpecTree () -> Maybe T.TestTree
-specTreeToTestTree spec_tree =
-  case spec_tree of
-    H.Node name spec_trees ->
-      Just (T.testGroup name (mapMaybe specTreeToTestTree spec_trees))
-    H.NodeWithCleanup cleanup spec_trees ->
-      T.WithResource (T.ResourceSpec (return ()) cleanup) . const <$> test_tree
-     where
-      test_tree :: Maybe T.TestTree
-      test_tree = specTreeToTestTree (H.Node "(unnamed)" spec_trees)
-    H.Leaf item -> do
-      guard (hspecItemIsFocused item)
-      Just (T.singleTest (H.itemRequirement item) (Item item))
+specTreeToTestTree = \case
+  Node name trees -> pure (T.testGroup name (mapMaybe specTreeToTestTree trees))
+  NodeWithCleanup cleanup trees -> do
+    tree <- specTreeToTestTree (H.Node "(unnamed)" trees)
+    pure (T.WithResource (T.ResourceSpec (return ()) cleanup) (const tree))
+  Leaf item -> do
+    guard (itemIsFocused item)
+    pure (T.singleTest (H.itemRequirement item) (Item item))
 
 newtype Item
   = Item (H.Item ())
-  deriving Typeable
+  deriving (Typeable)
 
 instance T.IsTest Item where
-  -- run :: T.OptionSet -> Item -> (T.Progress -> IO ()) -> IO T.Result
   run opts (Item item) progress = do
-    qc_args <- tastyOptionSetToQuickCheckArgs opts
-
-    let
-      pending_ :: String -> T.Result
-      pending_ =
-        case T.lookupOption opts of
-          TreatPendingAsFailure -> T.testFailed
-          TreatPendingAsSuccess -> T.testPassed
-
-    let
-      params :: H.Params
-      params = H.Params
-        { H.paramsQuickCheckArgs = qc_args
-        , H.paramsSmallCheckDepth = sc_depth
-        }
-
-#if MIN_VERSION_hspec(2,4,0) && !MIN_VERSION_hspec(2,5,0)
-    either handleUncaughtException (hspecResultToTastyResult pending_)
-#else
-    hspecResultToTastyResult pending_
-#endif
-      <$> hspecItemToExample item params ($ ()) hprogress
-
-   where
-    sc_depth :: Int
-    sc_depth =
-      case T.lookupOption opts of
-        TSC.SmallCheckDepth depth ->
-          depth
+    qcArgs <- optionSetToQuickCheckArgs opts
+    H.Result _ result <- itemExample item (params qcArgs) ($ ()) progress'
+    pure
+      ( case result of
+          H.Success -> T.testPassed ""
+          H.Pending _ reason ->
+            case T.lookupOption opts of
+              TreatPendingAsFailure -> T.testFailed reason'
+              TreatPendingAsSuccess -> T.testPassed reason'
+            where
+              reason' = "# PENDING: " ++ fromMaybe "No reason given" reason
+          H.Failure _ reason ->
+            case reason of
+              H.NoReason -> T.testFailed ""
+              H.Reason x -> T.testFailed x
+              H.ExpectedButGot preface expected actual ->
+                T.testFailed . unlines . catMaybes $
+                  [ preface,
+                    Just ("expected: " ++ expected),
+                    Just (" but got: " ++ actual)
+                  ]
+              H.Error _ exception -> T.testFailed ("uncaught exception: " ++ H.formatException exception)
+      )
+    where
+      params qcArgs =
+        H.Params
+          { H.paramsQuickCheckArgs = qcArgs,
+            H.paramsSmallCheckDepth =
+              case T.lookupOption opts of
+                TSC.SmallCheckDepth depth ->
+                  depth
+          }
 
-    hprogress :: H.Progress -> IO ()
-    hprogress (x,y) =
-      progress T.Progress
-        { T.progressText    = ""
-        , T.progressPercent = fromIntegral x / fromIntegral y
-        }
+      progress' (x, y) =
+        progress
+          T.Progress
+            { T.progressText = "",
+              T.progressPercent = fromIntegral x / fromIntegral y
+            }
 
-  -- testOptions :: Tagged Item [T.OptionDescription]
   testOptions =
-    return
-      [ T.Option (Proxy :: Proxy TreatPendingAs)
-      , T.Option (Proxy :: Proxy TQC.QuickCheckTests)
-      , T.Option (Proxy :: Proxy TQC.QuickCheckReplay)
-      , T.Option (Proxy :: Proxy TQC.QuickCheckMaxSize)
-      , T.Option (Proxy :: Proxy TQC.QuickCheckMaxRatio)
-      , T.Option (Proxy :: Proxy TSC.SmallCheckDepth)
+    pure
+      [ T.Option (Proxy :: Proxy TreatPendingAs),
+        T.Option (Proxy :: Proxy TQC.QuickCheckTests),
+        T.Option (Proxy :: Proxy TQC.QuickCheckReplay),
+        T.Option (Proxy :: Proxy TQC.QuickCheckMaxSize),
+        T.Option (Proxy :: Proxy TQC.QuickCheckMaxRatio),
+        T.Option (Proxy :: Proxy TSC.SmallCheckDepth)
       ]
 
-tastyOptionSetToQuickCheckArgs :: T.OptionSet -> IO QC.Args
-tastyOptionSetToQuickCheckArgs opts =
-#if MIN_VERSION_tasty_quickcheck(0,9,1)
-  snd <$> TQC.optionSetToArgs opts
-#else
-  return QC.stdArgs
-    { QC.chatty          = False
-    , QC.maxDiscardRatio = max_ratio
-    , QC.maxSize         = max_size
-    , QC.maxSuccess      = num_tests
-    , QC.replay          = replay
-    }
-  where
-    TQC.QuickCheckTests    num_tests = T.lookupOption opts
-    TQC.QuickCheckReplay   replay    = T.lookupOption opts
-    TQC.QuickCheckMaxSize  max_size  = T.lookupOption opts
-    TQC.QuickCheckMaxRatio max_ratio = T.lookupOption opts
-#endif
-
-hspecResultToTastyResult :: (String -> T.Result) -> H.Result -> T.Result
-#if MIN_VERSION_hspec(2,5,0)
-hspecResultToTastyResult pending_ (H.Result _ result) =
-#else
-hspecResultToTastyResult pending_ result =
-#endif
-  case result of
-    H.Success ->
-      T.testPassed ""
-
-#if MIN_VERSION_hspec(2,5,0)
-    H.Pending _ x ->
-#else
-    H.Pending x ->
-#endif
-      handleResultPending pending_ x
-
-#if MIN_VERSION_hspec(2,4,0)
-    H.Failure _ x ->
-      handleResultFailure x
-#elif MIN_VERSION_hspec(2,2,0)
-    H.Fail _ str -> T.testFailed str
-#else
-    H.Fail str -> T.testFailed str
-#endif
-
-hspecItemIsFocused :: H.Item a -> Bool
-hspecItemIsFocused =
-#if MIN_VERSION_hspec(2,6,0)
-  H.itemIsFocused
-#else
-  const True
-#endif
-
-hspecItemToExample
-  :: H.Item a
-  -> H.Params
-  -> (H.ActionWith a -> IO ())
-  -> H.ProgressCallback
-  -> IO H.Result
-#if MIN_VERSION_hspec(2,6,0)
-hspecItemToExample (H.Item _ _ _ _ ex) = ex
-#else
-hspecItemToExample (H.Item _ _ _ ex) = ex
-#endif
-
-
-handleResultPending :: (String -> T.Result) -> Maybe String -> T.Result
-handleResultPending pending_ x =
-  pending_ ("# PENDING: " ++ fromMaybe "No reason given" x)
-
--- FailureReason
---
--- - Introduced in 2.4.0
--- - Error constructor added in 2.5.0
-#if MIN_VERSION_hspec(2,4,0)
-handleResultFailure :: H.FailureReason -> T.Result
-handleResultFailure reason =
-  case reason of
-    H.NoReason -> T.testFailed ""
-    H.Reason x -> T.testFailed x
-    H.ExpectedButGot preface expected actual ->
-      T.testFailed . unlines . catMaybes $
-        [ preface
-        , Just ("expected: " ++ expected)
-        , Just (" but got: " ++ actual)
-        ]
-#if MIN_VERSION_hspec(2,5,0)
-    H.Error _ ex ->
-      handleUncaughtException ex
-#endif
-#endif
-
-handleUncaughtException :: SomeException -> T.Result
-handleUncaughtException ex =
-  T.testFailed ("uncaught exception: " ++ H.formatException ex)
-
 -- | How to treat @hspec@ pending tests.
 --
 -- @tasty@ does not have the concept of pending tests, so we must map them to
@@ -285,11 +172,10 @@
   defaultValue =
     TreatPendingAsFailure
 
-  parseValue s =
-    case s of
-      "failure" -> Just TreatPendingAsFailure
-      "success" -> Just TreatPendingAsSuccess
-      _         -> Nothing
+  parseValue = \case
+    "failure" -> Just TreatPendingAsFailure
+    "success" -> Just TreatPendingAsSuccess
+    _ -> Nothing
 
   optionName =
     pure "treat-pending-as"
diff --git a/src/Test/Tasty/Hspec/Compat.hs b/src/Test/Tasty/Hspec/Compat.hs
new file mode 100644
--- /dev/null
+++ b/src/Test/Tasty/Hspec/Compat.hs
@@ -0,0 +1,83 @@
+{-# LANGUAGE CPP #-}
+
+module Test.Tasty.Hspec.Compat
+  ( itemExample,
+    itemIsFocused,
+    focus,
+    optionSetToQuickCheckArgs,
+
+    pattern Leaf,
+    pattern Node,
+    pattern NodeWithCleanup,
+  )
+where
+
+import qualified Test.Hspec as Hspec
+import qualified Test.Hspec.Core.Spec as Hspec
+import qualified Test.QuickCheck as QuickCheck
+import qualified Test.Tasty.Options as Tasty
+import qualified Test.Tasty.QuickCheck as Tasty.QuickCheck
+
+{-# COMPLETE Leaf, Node, NodeWithCleanup #-}
+
+pattern Leaf :: a -> Hspec.Tree c a
+pattern Leaf item <-
+  Hspec.Leaf item
+
+pattern Node :: String -> [Hspec.Tree c a] -> Hspec.Tree c a
+pattern Node name trees <-
+  Hspec.Node name trees
+
+pattern NodeWithCleanup :: c -> [Hspec.Tree c a] -> Hspec.Tree c a
+pattern NodeWithCleanup cleanup trees <-
+#if MIN_VERSION_hspec(2,8,0)
+  Hspec.NodeWithCleanup _loc cleanup trees
+#else
+  Hspec.NodeWithCleanup cleanup trees
+#endif
+
+itemExample :: Hspec.Item a -> Hspec.Params -> (Hspec.ActionWith a -> IO ()) -> Hspec.ProgressCallback -> IO Hspec.Result
+itemExample item =
+  case item of
+#if MIN_VERSION_hspec(2,6,0)
+    Hspec.Item _ _ _ _ example -> example
+#else
+    Hspec.Item _ _ _ example -> example
+#endif
+
+itemIsFocused :: Hspec.Item a -> Bool
+itemIsFocused =
+#if MIN_VERSION_hspec(2,6,0)
+  Hspec.itemIsFocused
+#else
+  const True
+#endif
+
+focus :: Hspec.Spec -> Hspec.Spec
+focus =
+#if MIN_VERSION_hspec(2,6,0)
+  Hspec.focus
+#else
+  id
+#endif
+
+optionSetToQuickCheckArgs :: Tasty.OptionSet -> IO QuickCheck.Args
+optionSetToQuickCheckArgs opts =
+#if MIN_VERSION_tasty_quickcheck(0,9,1)
+  snd <$> Tasty.QuickCheck.optionSetToArgs opts
+#else
+  pure
+    QuickCheck.stdArgs
+      { QuickCheck.chatty = False,
+        QuickCheck.maxDiscardRatio = max_ratio,
+        QuickCheck.maxSize = max_size,
+        QuickCheck.maxSuccess = num_tests,
+        QuickCheck.replay = replay
+      }
+  where
+    Tasty.QuickCheck.QuickCheckTests num_tests = T.lookupOption opts
+    Tasty.QuickCheck.QuickCheckReplay replay = T.lookupOption opts
+    Tasty.QuickCheck.QuickCheckMaxSize max_size = T.lookupOption opts
+    Tasty.QuickCheck.QuickCheckMaxRatio max_ratio = T.lookupOption opts
+#endif
+
diff --git a/tasty-hspec.cabal b/tasty-hspec.cabal
--- a/tasty-hspec.cabal
+++ b/tasty-hspec.cabal
@@ -1,6 +1,6 @@
 cabal-version:       2.0
 name:                tasty-hspec
-version:             1.1.6
+version:             1.1.7
 synopsis:            Hspec support for the Tasty test framework.
 description:         This package provides a Tasty provider for Hspec test
                      suites.
@@ -25,45 +25,24 @@
   location: https://github.com/mitchellwrosen/tasty-hspec.git
 
 library
-  exposed-modules:     Test.Tasty.Hspec
-  hs-source-dirs:      src
-  build-depends:       base
-                            ^>= 4.9
-                         || ^>= 4.10
-                         || ^>= 4.11
-                         || ^>= 4.12
-                         || ^>= 4.13
-                         || ^>= 4.14
-                     , hspec >= 2 && < 2.8
-                     , hspec-core >= 2 && < 2.8
-                     , QuickCheck
-                            ^>= 2.7
-                         || ^>= 2.8
-                         || ^>= 2.9
-                         || ^>= 2.10
-                         || ^>= 2.11
-                         || ^>= 2.12
-                         || ^>= 2.13
-                         || ^>= 2.14
-                     , tasty
-                            ^>= 0.8
-                         || ^>= 0.9
-                         || ^>= 0.10
-                         || ^>= 0.11
-                         || ^>= 0.12
-                         || ^>= 1.0
-                         || ^>= 1.1
-                         || ^>= 1.2
-                         || ^>= 1.3
-                         || ^>= 1.4
-                     , tasty-smallcheck >= 0.1 && < 0.9
-                     -- 0.9 is missing 'optionSetToArgs'
-                     , tasty-quickcheck >=0.3 && <0.9 || ^>=0.9.1 || ^>= 0.10
+  build-depends:
+    base ^>= 4.9 || ^>= 4.10 || ^>= 4.11 || ^>= 4.12 || ^>= 4.13 || ^>= 4.14 || ^>= 4.15,
+    hspec >= 2.5 && < 2.9,
+    hspec-core >= 2.5 && < 2.9,
+    QuickCheck ^>= 2.7 || ^>= 2.8 || ^>= 2.9 || ^>= 2.10 || ^>= 2.11 || ^>= 2.12 || ^>= 2.13 || ^>= 2.14,
+    tasty ^>= 0.8 || ^>= 0.9 || ^>= 0.10 || ^>= 0.11 || ^>= 0.12 || ^>= 1.0 || ^>= 1.1 || ^>= 1.2 || ^>= 1.3 || ^>= 1.4,
+    tasty-smallcheck >= 0.1 && < 0.9,
+    -- 0.9 is missing 'optionSetToArgs'
+    tasty-quickcheck >=0.3 && <0.9 || ^>=0.9.1 || ^>= 0.10
   if impl(ghc < 7.8)
     build-depends:     tagged >= 0.2
-  other-extensions:    CPP
-                     , DeriveDataTypeable
-  default-language:    Haskell2010
-  ghc-options:         -Wall
+  default-extensions:
+    LambdaCase
+    PatternSynonyms
+  default-language: Haskell2010
+  exposed-modules: Test.Tasty.Hspec
+  ghc-options: -Wall
   if impl(ghc >= 8.0)
-    ghc-options:       -Wcompat
+    ghc-options: -Wcompat
+  hs-source-dirs: src
+  other-modules: Test.Tasty.Hspec.Compat
