diff --git a/Text/Pandoc/Builder.hs b/Text/Pandoc/Builder.hs
--- a/Text/Pandoc/Builder.hs
+++ b/Text/Pandoc/Builder.hs
@@ -166,7 +166,6 @@
 where
 import Text.Pandoc.Definition
 import Data.String
-import Data.Monoid
 import qualified Data.Map as M
 import Data.Sequence (Seq, (|>), viewr, viewl, ViewR(..), ViewL(..))
 import qualified Data.Sequence as Seq
@@ -177,6 +176,11 @@
 import Data.Data
 import Control.Arrow ((***))
 import GHC.Generics (Generic)
+#if MIN_VERSION_base(4,9,0)
+import Data.Semigroup
+#else
+import Data.Monoid
+#endif
 
 #if MIN_VERSION_base(4,5,0)
 -- (<>) is defined in Data.Monoid
@@ -209,10 +213,40 @@
 type Inlines = Many Inline
 type Blocks  = Many Block
 
+#if MIN_VERSION_base(4,9,0)
+deriving instance Semigroup Blocks
+#endif
 deriving instance Monoid Blocks
 
+#if MIN_VERSION_base(4,9,0)
+instance Semigroup Inlines where
+  (Many xs) <> (Many ys) =
+    case (viewr xs, viewl ys) of
+      (EmptyR, _) -> Many ys
+      (_, EmptyL) -> Many xs
+      (xs' :> x, y :< ys') -> Many (meld <> ys')
+        where meld = case (x, y) of
+                          (Space, Space)     -> xs' |> Space
+                          (Space, SoftBreak) -> xs' |> SoftBreak
+                          (SoftBreak, Space) -> xs' |> SoftBreak
+                          (Str t1, Str t2)   -> xs' |> Str (t1 <> t2)
+                          (Emph i1, Emph i2) -> xs' |> Emph (i1 <> i2)
+                          (Strong i1, Strong i2) -> xs' |> Strong (i1 <> i2)
+                          (Subscript i1, Subscript i2) -> xs' |> Subscript (i1 <> i2)
+                          (Superscript i1, Superscript i2) -> xs' |> Superscript (i1 <> i2)
+                          (Strikeout i1, Strikeout i2) -> xs' |> Strikeout (i1 <> i2)
+                          (Space, LineBreak) -> xs' |> LineBreak
+                          (LineBreak, Space) -> xs' |> LineBreak
+                          (SoftBreak, LineBreak) -> xs' |> LineBreak
+                          (LineBreak, SoftBreak) -> xs' |> LineBreak
+                          (SoftBreak, SoftBreak) -> xs' |> SoftBreak
+                          _                  -> xs' |> x |> y
 instance Monoid Inlines where
   mempty = Many mempty
+  mappend = (<>)
+#else
+instance Monoid Inlines where
+  mempty = Many mempty
   (Many xs) `mappend` (Many ys) =
     case (viewr xs, viewl ys) of
       (EmptyR, _) -> Many ys
@@ -234,6 +268,7 @@
                           (LineBreak, SoftBreak) -> xs' |> LineBreak
                           (SoftBreak, SoftBreak) -> xs' |> SoftBreak
                           _                  -> xs' |> x |> y
+#endif
 
 instance IsString Inlines where
    fromString = text
diff --git a/Text/Pandoc/Definition.hs b/Text/Pandoc/Definition.hs
--- a/Text/Pandoc/Definition.hs
+++ b/Text/Pandoc/Definition.hs
@@ -90,24 +90,44 @@
 #endif
 import Paths_pandoc_types (version)
 import Data.Version (Version, versionBranch)
+#if MIN_VERSION_base(4,9,0)
+import Data.Semigroup
+#endif
 
 data Pandoc = Pandoc Meta [Block]
               deriving (Eq, Ord, Read, Show, Typeable, Data, Generic)
 
+#if MIN_VERSION_base(4,9,0)
+instance Semigroup Pandoc where
+  (Pandoc m1 bs1) <> (Pandoc m2 bs2) =
+    Pandoc (m1 <> m2) (bs1 <> bs2)
 instance Monoid Pandoc where
   mempty = Pandoc mempty mempty
+  mappend = (<>)
+#else
+instance Monoid Pandoc where
+  mempty = Pandoc mempty mempty
   (Pandoc m1 bs1) `mappend` (Pandoc m2 bs2) =
     Pandoc (m1 `mappend` m2) (bs1 `mappend` bs2)
+#endif
 
 -- | Metadata for the document:  title, authors, date.
 newtype Meta = Meta { unMeta :: M.Map String MetaValue }
                deriving (Eq, Ord, Show, Read, Typeable, Data, Generic)
 
+#if MIN_VERSION_base(4,9,0)
+instance Semigroup Meta where
+  (Meta m1) <> (Meta m2) = Meta (M.union m1 m2)
+  -- note: M.union is left-biased, so if there are fields in both m1
+  -- and m2, m1 wins.
 instance Monoid Meta where
   mempty = Meta (M.empty)
+  mappend = (<>)
+#else
+instance Monoid Meta where
+  mempty = Meta (M.empty)
   (Meta m1) `mappend` (Meta m2) = Meta (M.union m1 m2)
-  -- note: M.union is left-biased, so if there are fields in both m1
-  -- and m2, m1 wins.
+#endif
 
 data MetaValue = MetaMap (M.Map String MetaValue)
                | MetaList [MetaValue]
diff --git a/changelog b/changelog
--- a/changelog
+++ b/changelog
@@ -1,3 +1,10 @@
+[1.17.4]
+
+  * Add Semigroup instances for Pandoc, Meta, Inlines, Blocks
+    (if base >= 4.9).  This is needed for the library to compile
+    with ghc 8.4.
+  * Bumped criterion upper bound.
+
 [1.17.3.1]
 
   * Bumped upper bounds for criterion and QuickCheck.
diff --git a/pandoc-types.cabal b/pandoc-types.cabal
--- a/pandoc-types.cabal
+++ b/pandoc-types.cabal
@@ -1,5 +1,5 @@
 Name:                pandoc-types
-Version:             1.17.3.1
+Version:             1.17.4
 Synopsis:            Types for representing a structured document
 Description:         @Text.Pandoc.Definition@ defines the 'Pandoc' data
                      structure, which is used by pandoc to represent
@@ -51,7 +51,7 @@
                      syb >= 0.1 && < 0.8,
                      ghc-prim >= 0.2,
                      bytestring >= 0.9 && < 0.11,
-                     aeson >= 0.6.2 && < 1.3,
+                     aeson >= 0.6.2 && < 1.4,
                      transformers >= 0.2 && < 0.6,
                      QuickCheck >= 2
   if impl(ghc < 7.10)
@@ -67,7 +67,7 @@
   build-depends:       base,
                        pandoc-types,
                        syb,
-                       aeson >= 0.6.2 && < 1.3,
+                       aeson >= 0.6.2 && < 1.4,
                        containers >= 0.3,
                        bytestring >= 0.9 && < 0.11,
                        test-framework >= 0.3 && < 0.9,
@@ -84,5 +84,5 @@
   hs-source-dirs:  benchmark
   build-depends:   pandoc-types,
                    base >= 4.2 && < 5,
-                   criterion >= 1.0 && < 1.4
+                   criterion >= 1.0 && < 1.5
   ghc-options:   -rtsopts -Wall -fno-warn-unused-do-bind -O2
