diff --git a/CHANGELOG.md b/CHANGELOG.md
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,9 @@
+## MMark 0.0.7.2
+
+* Uses Megaparsec 8.0.0.
+
+* Dropped suppot for GHC 8.2.
+
 ## MMark 0.0.7.1
 
 * Builds with `yaml-0.11.1.0`.
diff --git a/Text/MMark.hs b/Text/MMark.hs
--- a/Text/MMark.hs
+++ b/Text/MMark.hs
@@ -111,6 +111,7 @@
 -- "Text.MMark.Extension" module, which has some documentation focusing on
 -- extension writing.
 
+{-# LANGUAGE CPP             #-}
 {-# LANGUAGE RecordWildCards #-}
 
 module Text.MMark
@@ -131,11 +132,14 @@
 where
 
 import Data.Aeson
-import Data.Semigroup ((<>))
 import Text.MMark.Parser (MMarkErr (..), parse)
 import Text.MMark.Render (render)
 import Text.MMark.Type
 import qualified Control.Foldl as L
+
+#if !MIN_VERSION_base(4,13,0)
+import Data.Semigroup ((<>))
+#endif
 
 ----------------------------------------------------------------------------
 -- Extensions
diff --git a/Text/MMark/Parser.hs b/Text/MMark/Parser.hs
--- a/Text/MMark/Parser.hs
+++ b/Text/MMark/Parser.hs
@@ -33,7 +33,6 @@
 import Data.Maybe (isNothing, fromJust, catMaybes, isJust)
 import Data.Monoid (Any (..))
 import Data.Ratio ((%))
-import Data.Semigroup (Semigroup (..))
 import Data.Text (Text)
 import Lens.Micro ((^.))
 import Text.MMark.Parser.Internal
@@ -56,6 +55,10 @@
 import qualified Text.Megaparsec.Char.Lexer as L
 import qualified Text.URI                   as URI
 
+#if !MIN_VERSION_base(4,13,0)
+import Data.Semigroup (Semigroup (..))
+#endif
+
 #if !defined(ghcjs_HOST_OS)
 import qualified Data.Yaml                  as Yaml
 #endif
@@ -436,9 +439,8 @@
       (Just True,  Nothing) -> return ()
       _                     -> hidden eof <|> eol
     conflict <- registerReference dlabel (uri, mtitle)
-    when conflict $ do
-      setOffset o
-      customFailure (DuplicateReferenceDefinition dlabel)
+    when conflict $
+      customFailure' o (DuplicateReferenceDefinition dlabel)
     Nothing <$ sc
   where
     recover err =
@@ -779,20 +781,15 @@
     withRef =
       pRefLabel >>= uncurry lookupRef
     collapsed o inlines = do
-      -- NOTE We need to do these manipulations so the failure caused by
-      -- @'string' "[]"@ does not overwrite our custom failures.
-      o' <- getOffset
-      setOffset o
-      (void . hidden . string) "[]"
-      setOffset (o' + 2)
+      region (setErrorOffset o) $
+        (void . hidden . string) "[]"
       lookupRef o (mkLabel inlines)
     shortcut o inlines =
       lookupRef o (mkLabel inlines)
     lookupRef o dlabel =
       lookupReference dlabel >>= \case
-        Left names -> do
-          setOffset o
-          customFailure (CouldNotFindReferenceDefinition dlabel names)
+        Left names ->
+          customFailure' o (CouldNotFindReferenceDefinition dlabel names)
         Right x ->
           return x
     mkLabel = T.unwords . T.words . asPlainText
@@ -860,9 +857,8 @@
     , r (SingleFrame SubscriptFrame)
     , r (SingleFrame SuperscriptFrame) ]
   let dels = inlineStateDel st
-      failNow = do
-        setOffset o
-        (customFailure . NonFlankingDelimiterRun . toNesTokens) dels
+      failNow =
+        customFailure' o (NonFlankingDelimiterRun (toNesTokens dels))
   lch <- getLastChar
   rch <- getNextChar OtherChar
   when (lch >= rch) failNow
@@ -879,9 +875,8 @@
         other -> other
   o <- getOffset
   (void . expectingInlineContent . string) dels
-  let failNow = do
-        setOffset o
-        (customFailure . NonFlankingDelimiterRun . toNesTokens) dels
+  let failNow =
+        customFailure' o (NonFlankingDelimiterRun (toNesTokens dels))
   lch <- getLastChar
   rch <- getNextChar SpaceChar
   when (lch <= rch) failNow
@@ -971,9 +966,8 @@
   name <- try . region f $ between (char '&') (char ';')
     (takeWhile1P Nothing Char.isAlphaNum <?> "HTML5 entity name")
   case HM.lookup name htmlEntityMap of
-    Nothing -> do
-      setOffset o
-      customFailure (UnknownHtmlEntityName name)
+    Nothing ->
+      customFailure' o (UnknownHtmlEntityName name)
     Just txt -> return (T.unpack txt)
 
 -- | Parse a numeric character using the given numeric parser.
@@ -984,9 +978,7 @@
   let f = between (string "&#") (char ';')
   n   <- try (f (char' 'x' *> L.hexadecimal)) <|> f L.decimal
   if n == 0 || n > fromEnum (maxBound :: Char)
-    then do
-      setOffset o
-      customFailure (InvalidNumericCharacter n)
+    then customFailure' o (InvalidNumericCharacter n)
     else return (Char.chr n)
 
 sc :: MonadParsec e Text m => m ()
@@ -1191,7 +1183,10 @@
 #if MIN_VERSION_yaml(0,11,1)
   Yaml.LoadSettingsException _ _ -> (Nothing, "loading settings exception")
 #endif
+#if MIN_VERSION_yaml(0,11,2)
+  Yaml.NonStringKey _ -> (Nothing, "non string key")
 #endif
+#endif
 
 emptyIspSpan :: Isp
 emptyIspSpan = IspSpan 0 ""
@@ -1245,3 +1240,15 @@
 
 bakeText :: (String -> String) -> Text
 bakeText = T.pack . reverse . ($ [])
+
+-- | Report custom failure at specified location.
+
+customFailure'
+  :: MonadParsec MMarkErr Text m
+  => Int
+  -> MMarkErr
+  -> m a
+customFailure' o e =
+  parseError $ FancyError
+    o
+    (E.singleton (ErrorCustom e))
diff --git a/Text/MMark/Parser/Internal.hs b/Text/MMark/Parser/Internal.hs
--- a/Text/MMark/Parser/Internal.hs
+++ b/Text/MMark/Parser/Internal.hs
@@ -239,7 +239,7 @@
   :: FilePath          -- ^ File name to use
   -> Text              -- ^ Input
   -> Int               -- ^ Starting offset
-  -> M.State Text
+  -> M.State Text e
 mkInitialState file input offset = M.State
   { stateInput = input
   , stateOffset = offset
@@ -250,6 +250,7 @@
     , pstateTabWidth = mkPos 4
     , pstateLinePrefix = ""
     }
+  , stateParseErrors = []
   }
 
 -- | Locally change state in a state monad and then restore it back.
diff --git a/Text/MMark/Parser/Internal/Type.hs b/Text/MMark/Parser/Internal/Type.hs
--- a/Text/MMark/Parser/Internal/Type.hs
+++ b/Text/MMark/Parser/Internal/Type.hs
@@ -9,6 +9,7 @@
 --
 -- Types for the internal helper definitions for the parser.
 
+{-# LANGUAGE CPP                        #-}
 {-# LANGUAGE DeriveDataTypeable         #-}
 {-# LANGUAGE DeriveGeneric              #-}
 {-# LANGUAGE GeneralizedNewtypeDeriving #-}
@@ -50,7 +51,6 @@
 import Data.List (intercalate)
 import Data.List.NonEmpty (NonEmpty (..))
 import Data.Proxy
-import Data.Semigroup ((<>))
 import Data.Text (Text)
 import Data.Typeable (Typeable)
 import GHC.Generics
@@ -61,6 +61,10 @@
 import qualified Data.HashMap.Strict  as HM
 import qualified Data.List.NonEmpty   as NE
 import qualified Data.Text            as T
+
+#if !MIN_VERSION_base(4,13,0)
+import Data.Semigroup ((<>))
+#endif
 
 ----------------------------------------------------------------------------
 -- Block-level parser state
diff --git a/Text/MMark/Render.hs b/Text/MMark/Render.hs
--- a/Text/MMark/Render.hs
+++ b/Text/MMark/Render.hs
@@ -9,7 +9,6 @@
 --
 -- MMark rendering machinery.
 
-{-# LANGUAGE CPP               #-}
 {-# LANGUAGE LambdaCase        #-}
 {-# LANGUAGE OverloadedStrings #-}
 {-# LANGUAGE RecordWildCards   #-}
@@ -30,10 +29,6 @@
 import qualified Data.List.NonEmpty as NE
 import qualified Data.Text          as T
 import qualified Text.URI           as URI
-
-#if !MIN_VERSION_base(4,11,0)
-import Data.Semigroup
-#endif
 
 -- | Render a 'MMark' markdown document. You can then render @'Html' ()@ to
 -- various things:
diff --git a/Text/MMark/Type.hs b/Text/MMark/Type.hs
--- a/Text/MMark/Type.hs
+++ b/Text/MMark/Type.hs
@@ -10,7 +10,6 @@
 -- Internal type definitions. Some of these are re-exported in the public
 -- modules.
 
-{-# LANGUAGE CPP                #-}
 {-# LANGUAGE DeriveDataTypeable #-}
 {-# LANGUAGE DeriveFoldable     #-}
 {-# LANGUAGE DeriveFunctor      #-}
@@ -41,10 +40,6 @@
 import GHC.Generics
 import Lucid
 import Text.URI (URI (..))
-
-#if !MIN_VERSION_base(4,11,0)
-import Data.Semigroup
-#endif
 
 -- | Representation of complete markdown document. You can't look inside of
 -- 'MMark' on purpose. The only way to influence an 'MMark' document you
diff --git a/mmark.cabal b/mmark.cabal
--- a/mmark.cabal
+++ b/mmark.cabal
@@ -1,7 +1,7 @@
 name:                 mmark
-version:              0.0.7.1
+version:              0.0.7.2
 cabal-version:        1.18
-tested-with:          GHC==8.2.2, GHC==8.4.4, GHC==8.6.5
+tested-with:          GHC==8.4.4, GHC==8.6.5, GHC==8.8.1
 license:              BSD3
 license-file:         LICENSE.md
 author:               Mark Karpov <markkarpov92@gmail.com>
@@ -28,7 +28,7 @@
 
 library
   build-depends:      aeson            >= 0.11 && < 1.5
-                    , base             >= 4.10 && < 5.0
+                    , base             >= 4.11 && < 5.0
                     , case-insensitive >= 1.2  && < 1.3
                     , containers       >= 0.5  && < 0.7
                     , deepseq          >= 1.3  && < 1.5
@@ -38,7 +38,7 @@
                     , hashable         >= 1.0.1.1 && < 1.4
                     , html-entity-map  >= 0.1  && < 0.2
                     , lucid            >= 2.6  && < 3.0
-                    , megaparsec       >= 7.0  && < 8.0
+                    , megaparsec       >= 8.0  && < 9.0
                     , microlens        >= 0.4  && < 0.5
                     , microlens-th     >= 0.4  && < 0.5
                     , modern-uri       >= 0.3  && < 0.4
@@ -67,7 +67,6 @@
                       -Wincomplete-record-updates
                       -Wincomplete-uni-patterns
                       -Wnoncanonical-monad-instances
-                      -Wnoncanonical-monadfail-instances
   if impl(ghcjs)
     ghcjs-options:    +RTS -K1G -RTS -Wall
 
@@ -79,12 +78,12 @@
   type:               exitcode-stdio-1.0
   build-depends:      QuickCheck       >= 2.4  && < 3.0
                     , aeson            >= 0.11 && < 1.5
-                    , base             >= 4.10 && < 5.0
+                    , base             >= 4.11 && < 5.0
                     , foldl            >= 1.2  && < 1.5
                     , hspec            >= 2.0  && < 3.0
                     , hspec-megaparsec >= 2.0  && < 3.0
                     , lucid            >= 2.6  && < 3.0
-                    , megaparsec       >= 7.0  && < 8.0
+                    , megaparsec       >= 8.0  && < 9.0
                     , mmark
                     , modern-uri       >= 0.3  && < 0.4
                     , text             >= 0.2  && < 1.3
@@ -103,7 +102,7 @@
   main-is:            Main.hs
   hs-source-dirs:     bench/speed
   type:               exitcode-stdio-1.0
-  build-depends:      base             >= 4.10 && < 5.0
+  build-depends:      base             >= 4.11 && < 5.0
                     , criterion        >= 0.6.2.1 && < 1.6
                     , mmark
                     , text             >= 0.2 && < 1.3
@@ -119,7 +118,7 @@
   main-is:            Main.hs
   hs-source-dirs:     bench/memory
   type:               exitcode-stdio-1.0
-  build-depends:      base             >= 4.10 && < 5.0
+  build-depends:      base             >= 4.11 && < 5.0
                     , mmark
                     , text             >= 0.2 && < 1.3
                     , weigh            >= 0.0.4
diff --git a/tests/Text/MMark/TestUtils.hs b/tests/Text/MMark/TestUtils.hs
--- a/tests/Text/MMark/TestUtils.hs
+++ b/tests/Text/MMark/TestUtils.hs
@@ -1,3 +1,4 @@
+{-# LANGUAGE CPP               #-}
 {-# LANGUAGE OverloadedStrings #-}
 
 module Text.MMark.TestUtils
@@ -14,7 +15,6 @@
 where
 
 import Control.Monad
-import Data.Semigroup ((<>))
 import Data.Text (Text)
 import Test.Hspec
 import Text.MMark (MMark, MMarkErr)
@@ -23,6 +23,10 @@
 import qualified Data.Text.Lazy     as TL
 import qualified Lucid              as L
 import qualified Text.MMark         as MMark
+
+#if !MIN_VERSION_base(4,13,0)
+import Data.Semigroup ((<>))
+#endif
 
 ----------------------------------------------------------------------------
 -- Document creation and rendering
