diff --git a/heist.cabal b/heist.cabal
--- a/heist.cabal
+++ b/heist.cabal
@@ -1,5 +1,5 @@
 name:           heist
-version:        1.0.1.2
+version:        1.0.1.3
 synopsis:       An Haskell template system supporting both HTML5 and XML.
 description:
     Heist is a powerful template system that supports both HTML5 and XML.
@@ -30,9 +30,16 @@
 cabal-version:  >= 1.8.0.4
 homepage:       http://snapframework.com/
 category:       Web, Snap
-Tested-With:    GHC == 7.4.2, GHC == 7.6.3, GHC == 7.8.4, GHC == 7.10.3
-                GHC == 8.0.1, GHC == 8.2.2
 
+Tested-With:
+  GHC == 7.4.2,
+  GHC == 7.6.3,
+  GHC == 7.8.4,
+  GHC == 7.10.3,
+  GHC == 8.0.1,
+  GHC == 8.2.2,
+  GHC == 8.4.1
+
 extra-source-files:
   .ghci,
   CONTRIBUTORS,
@@ -152,9 +159,9 @@
     Heist.Interpreted.Internal
 
   build-depends:
-    aeson                      >= 0.6     && < 1.3,
+    aeson                      >= 0.6     && < 1.4,
     attoparsec                 >= 0.10    && < 0.14,
-    base                       >= 4.5     && < 5,
+    base                       >= 4.5     && < 4.12,
     blaze-builder              >= 0.2     && < 0.5,
     blaze-html                 >= 0.4     && < 0.10,
     bytestring                 >= 0.9     && < 0.11,
@@ -165,19 +172,22 @@
     filepath                   >= 1.3     && < 1.5,
     hashable                   >= 1.1     && < 1.3,
     lifted-base                >= 0.2     && < 0.3,
-    map-syntax                 >= 0.2     && < 0.3,
+    map-syntax                 >= 0.2     && < 0.4,
     monad-control              >= 0.3     && < 1.1,
     mtl                        >= 2.0     && < 2.3,
     process                    >= 1.1     && < 1.7,
     random                     >= 1.0.1.0 && < 1.2,
     text                       >= 0.10    && < 1.3,
-    time                       >= 1.1     && < 1.9,
+    time                       >= 1.1     && < 1.10,
     transformers               >= 0.3     && < 0.6,
     transformers-base          >= 0.4     && < 0.5,
     unordered-containers       >= 0.1.4   && < 0.3,
     vector                     >= 0.9     && < 0.13,
     xmlhtml                    >= 0.2.3.5 && < 0.3
 
+  if !impl(ghc >= 8.0)
+    build-depends: semigroups >= 0.16 && < 0.19
+
   if impl(ghc >= 6.12.0)
     ghc-options: -Wall -fwarn-tabs -funbox-strict-fields
                  -fno-warn-unused-do-bind
@@ -208,15 +218,15 @@
 
   build-depends:
     HUnit                      >= 1.2      && < 2,
-    QuickCheck                 >= 2        && < 2.11,
-    lens                       >= 4.3      && < 4.16,
+    QuickCheck                 >= 2        && < 2.12,
+    lens                       >= 4.3      && < 4.17,
     test-framework             >= 0.4      && < 0.9,
     test-framework-hunit       >= 0.2.7    && < 0.4,
     test-framework-quickcheck2 >= 0.2.12.1 && < 0.4,
     aeson,
     attoparsec,
     base,
-    bifunctors >= 5.3 && < 5.5,
+    bifunctors >= 5.3 && < 5.6,
     blaze-builder,
     blaze-html,
     bytestring,
@@ -239,6 +249,10 @@
     unordered-containers,
     vector,
     xmlhtml
+
+  if !impl(ghc >= 8.0)
+    build-depends: semigroups >= 0.16 && < 0.19
+
   ghc-options: -Wall -fwarn-tabs -funbox-strict-fields -threaded
   Extensions: OverloadedStrings
 
@@ -249,7 +263,7 @@
 
   build-depends:
     HUnit,
-    criterion                 >= 1.0     && < 1.3,
+    criterion                 >= 1.0     && < 1.5,
     test-framework,
     test-framework-hunit,
 
@@ -281,6 +295,9 @@
     unordered-containers,
     vector,
     xmlhtml
+
+  if !impl(ghc >= 8.0)
+    build-depends: semigroups >= 0.16 && < 0.19
 
   ghc-options: -Wall -fwarn-tabs -funbox-strict-fields -threaded
                -fno-warn-unused-do-bind -rtsopts
diff --git a/src/Heist.hs b/src/Heist.hs
--- a/src/Heist.hs
+++ b/src/Heist.hs
@@ -91,6 +91,7 @@
 import           Control.Exception.Lifted
 import           Control.Monad.State
 import           Data.ByteString               (ByteString)
+import qualified Data.ByteString.Char8         as BC
 import qualified Data.ByteString               as B
 import           Data.Either
 import qualified Data.Foldable                 as F
@@ -98,7 +99,9 @@
 import qualified Data.HashMap.Strict           as Map
 import qualified Data.HeterogeneousEnvironment as HE
 import           Data.Map.Syntax
+#if !MIN_VERSION_base(4,11,0)
 import           Data.Monoid
+#endif
 import           Data.Text                     (Text)
 import qualified Data.Text                     as T
 import           System.Directory.Tree
@@ -306,12 +309,13 @@
            -> HeistT IO IO (Either String (TPath, DocumentFile))
 preprocess (tpath, docFile) = do
     let tname = tpathName tpath
+        die   = error $ "Preprocess failed because the template `"
+                     ++ BC.unpack tname
+                     ++ "` was not found in the template repository."
     !emdoc <- try $ I.evalWithDoctypes tname
               :: HeistT IO IO (Either SomeException (Maybe X.Document))
     let f !doc = (tpath, docFile { dfDoc = doc })
     return $! either (Left . show) (Right . maybe die f) emdoc
-  where
-    die = error "Preprocess didn't succeed!  This should never happen."
 
 
 ------------------------------------------------------------------------------
diff --git a/src/Heist/Internal/Types.hs b/src/Heist/Internal/Types.hs
--- a/src/Heist/Internal/Types.hs
+++ b/src/Heist/Internal/Types.hs
@@ -26,8 +26,10 @@
 
 #if !MIN_VERSION_base(4,8,0)
 import           Control.Applicative
-import           Data.Monoid
 #endif
+#if !MIN_VERSION_base(4,11,0)
+import           Data.Semigroup
+#endif
 
 ------------------------------------------------------------------------------
 import qualified Heist.Compiled.Internal       as C
@@ -154,12 +156,16 @@
     setter sc v = sc { _scCompiledTemplateFilter = v }
 
 
+instance Semigroup (SpliceConfig m) where
+    SpliceConfig a1 b1 c1 d1 e1 f1 <> SpliceConfig a2 b2 c2 d2 e2 f2 =
+      SpliceConfig (a1 <> a2) (b1 <> b2) (c1 <> c2)
+                   (d1 <> d2) (e1 <> e2) (\x -> f1 x && f2 x)
+
 instance Monoid (SpliceConfig m) where
     mempty = SpliceConfig mempty mempty mempty mempty mempty (const True)
-    mappend (SpliceConfig a1 b1 c1 d1 e1 f1)
-            (SpliceConfig a2 b2 c2 d2 e2 f2) =
-      SpliceConfig (mappend a1 a2) (mappend b1 b2) (mappend c1 c2)
-                   (mappend d1 d2) (mappend e1 e2) (\x -> f1 x && f2 x)
+#if !MIN_VERSION_base(4,11,0)
+    mappend = (<>)
+#endif
 
 
 data HeistConfig m = HeistConfig
diff --git a/src/Heist/Internal/Types/HeistState.hs b/src/Heist/Internal/Types/HeistState.hs
--- a/src/Heist/Internal/Types/HeistState.hs
+++ b/src/Heist/Internal/Types/HeistState.hs
@@ -45,6 +45,9 @@
 import           Data.HeterogeneousEnvironment (HeterogeneousEnvironment)
 import qualified Data.HeterogeneousEnvironment as HE
 import           Data.Map.Syntax
+#if !MIN_VERSION_base(4,11,0)
+import           Data.Semigroup
+#endif
 import           Data.Text                     (Text)
 import qualified Data.Text                     as T
 import           Data.Text.Encoding            (decodeUtf8)
@@ -122,13 +125,22 @@
 
 
 ------------------------------------------------------------------------------
-instance (Monad m, Monoid a) => Monoid (RuntimeSplice m a) where
-    mempty = return mempty
-
-    a `mappend` b = do
+instance (Monad m, Semigroup a) => Semigroup (RuntimeSplice m a) where
+    a <> b = do
         !x <- a
         !y <- b
-        return $! x `mappend` y
+        return $! x <> y
+
+
+#if !MIN_VERSION_base(4,11,0)
+instance (Monad m, Semigroup a, Monoid a) => Monoid (RuntimeSplice m a) where
+#else
+instance (Monad m, Monoid a) => Monoid (RuntimeSplice m a) where
+#endif
+    mempty = return mempty
+#if !MIN_VERSION_base(4,11,0)
+    mappend = (<>)
+#endif
 
 
 ------------------------------------------------------------------------------
diff --git a/src/Heist/Splices.hs b/src/Heist/Splices.hs
--- a/src/Heist/Splices.hs
+++ b/src/Heist/Splices.hs
@@ -57,8 +57,8 @@
 
 
 ------------------------------------------------------------------------------
--- | Implements an if/then/else conditional splice.  It splits its children
--- around the <else/> element to get the markup to be used for the two cases.
+-- | Implements an if\/then\/else conditional splice.  It splits its children
+-- around the \<else\/\> element to get the markup to be used for the two cases.
 ifElseISplice :: Monad m => Bool -> I.Splice m
 ifElseISplice cond = getParamNode >>= (rewrite . X.childNodes)
   where
@@ -68,8 +68,8 @@
 
 
 ------------------------------------------------------------------------------
--- | Implements an if/then/else conditional splice.  It splits its children
--- around the <else/> element to get the markup to be used for the two cases.
+-- | Implements an if\/then\/else conditional splice.  It splits its children
+-- around the \<else\/\> element to get the markup to be used for the two cases.
 ifElseCSplice :: Monad m => Bool -> C.Splice m
 ifElseCSplice cond = getParamNode >>= (rewrite . X.childNodes)
   where rewrite nodes = 
