diff --git a/ChangeLog.md b/ChangeLog.md
new file mode 100644
--- /dev/null
+++ b/ChangeLog.md
@@ -0,0 +1,5 @@
+## 3000.2.2
+
+- Add `Semigroup Html` instance
+- Update to `cabal-version:>=1.10`
+- Clean-up compiler warnings
diff --git a/README b/README
deleted file mode 100644
--- a/README
+++ /dev/null
@@ -1,2 +0,0 @@
-This package provides combinators for producing XHTML 1.0, including
-the Strict, Transitional and Frameset variants.
diff --git a/Text/XHtml.hs b/Text/XHtml.hs
--- a/Text/XHtml.hs
+++ b/Text/XHtml.hs
@@ -1,7 +1,3 @@
-#if __GLASGOW_HASKELL__ >= 701
-{-# LANGUAGE Safe #-}
-#endif
-
 -----------------------------------------------------------------------------
 -- |
 -- Module      :  Text.XHtml
diff --git a/Text/XHtml/BlockTable.hs b/Text/XHtml/BlockTable.hs
--- a/Text/XHtml/BlockTable.hs
+++ b/Text/XHtml/BlockTable.hs
@@ -1,7 +1,3 @@
-#if __GLASGOW_HASKELL__ >= 701
-{-# LANGUAGE Safe #-}
-#endif
-
 -----------------------------------------------------------------------------
 -- |
 -- Module      :  Text.XHtml.BlockTable
diff --git a/Text/XHtml/Debug.hs b/Text/XHtml/Debug.hs
--- a/Text/XHtml/Debug.hs
+++ b/Text/XHtml/Debug.hs
@@ -1,8 +1,4 @@
 {-# OPTIONS_HADDOCK hide #-}
--- #hide
-#if __GLASGOW_HASKELL__ >= 701
-{-# LANGUAGE Safe #-}
-#endif
 
 -- | This module contains functions for displaying
 --   HTML as a pretty tree.
diff --git a/Text/XHtml/Extras.hs b/Text/XHtml/Extras.hs
--- a/Text/XHtml/Extras.hs
+++ b/Text/XHtml/Extras.hs
@@ -1,7 +1,3 @@
-#if __GLASGOW_HASKELL__ >= 701
-{-# LANGUAGE Safe #-}
-#endif
-
 module Text.XHtml.Extras where
 
 import Text.XHtml.Internals
diff --git a/Text/XHtml/Frameset.hs b/Text/XHtml/Frameset.hs
--- a/Text/XHtml/Frameset.hs
+++ b/Text/XHtml/Frameset.hs
@@ -1,7 +1,3 @@
-#if __GLASGOW_HASKELL__ >= 701
-{-# LANGUAGE Safe #-}
-#endif
-
 -- | Produces XHTML 1.0 Frameset.
 module Text.XHtml.Frameset (
      -- * Data types
diff --git a/Text/XHtml/Frameset/Attributes.hs b/Text/XHtml/Frameset/Attributes.hs
--- a/Text/XHtml/Frameset/Attributes.hs
+++ b/Text/XHtml/Frameset/Attributes.hs
@@ -1,8 +1,4 @@
 {-# OPTIONS_HADDOCK hide #-}
--- #hide
-#if __GLASGOW_HASKELL__ >= 701
-{-# LANGUAGE Safe #-}
-#endif
 
 module Text.XHtml.Frameset.Attributes where
 
diff --git a/Text/XHtml/Frameset/Elements.hs b/Text/XHtml/Frameset/Elements.hs
--- a/Text/XHtml/Frameset/Elements.hs
+++ b/Text/XHtml/Frameset/Elements.hs
@@ -1,8 +1,4 @@
 {-# OPTIONS_HADDOCK hide #-}
--- #hide
-#if __GLASGOW_HASKELL__ >= 701
-{-# LANGUAGE Safe #-}
-#endif
 
 module Text.XHtml.Frameset.Elements where
 
diff --git a/Text/XHtml/Internals.hs b/Text/XHtml/Internals.hs
--- a/Text/XHtml/Internals.hs
+++ b/Text/XHtml/Internals.hs
@@ -1,13 +1,9 @@
 {-# OPTIONS_HADDOCK hide #-}
--- #hide
-#if __GLASGOW_HASKELL__ >= 701
-{-# LANGUAGE Safe #-}
-#endif
 
 -----------------------------------------------------------------------------
 -- |
 -- Module      :  Text.XHtml.internals
--- Copyright   :  (c) Andy Gill, and the Oregon Graduate Institute of 
+-- Copyright   :  (c) Andy Gill, and the Oregon Graduate Institute of
 --                Science and Technology, 1999-2001,
 --                (c) Bjorn Bringert, 2004-2006
 -- License     :  BSD-style (see the file LICENSE)
@@ -20,13 +16,13 @@
 module Text.XHtml.Internals where
 
 import Data.Char
-import Data.Monoid
+import qualified Data.Semigroup as Sem
 
 infixr 2 +++  -- combining Html
 infixr 7 <<   -- nesting Html
 infixl 8 !    -- adding optional arguments
 
--- 
+--
 -- * Data types
 --
 
@@ -35,7 +31,7 @@
 data HtmlElement
       = HtmlString String
         -- ^ ..just..plain..normal..text... but using &copy; and &amb;, etc.
-      | HtmlTag {                   
+      | HtmlTag {
               markupTag      :: String,
               markupAttrs    :: [HtmlAttr],
               markupContent  :: Html
@@ -53,7 +49,7 @@
 newtype Html = Html { getHtmlElements :: [HtmlElement] }
 
 
--- 
+--
 -- * Classes
 --
 
@@ -62,14 +58,18 @@
       showList htmls   = foldr (.) id (map shows htmls)
 
 instance Show HtmlAttr where
-      showsPrec _ (HtmlAttr str val) = 
+      showsPrec _ (HtmlAttr str val) =
               showString str .
               showString "=" .
               shows val
 
-instance Monoid Html where
+-- | @since 3000.2.2
+instance Sem.Semigroup Html where
+    (<>) = (+++)
+
+instance Sem.Monoid Html where
     mempty = noHtml
-    mappend = (+++)
+    mappend = (Sem.<>)
 
 -- | HTML is the class of things that can be validly put
 -- inside an HTML tag. So this can be one or more 'Html' elements,
@@ -122,12 +122,12 @@
               addAttrs html = html
 
 
--- 
+--
 -- * Html primitives and basic combinators
 --
 
 -- | Put something inside an HTML element.
-(<<) :: (HTML a) => 
+(<<) :: (HTML a) =>
         (Html -> b) -- ^ Parent
      -> a -- ^ Child
      -> b
@@ -179,13 +179,13 @@
 
 
 {-
-foldHtml :: (String -> [HtmlAttr] -> [a] -> a) 
+foldHtml :: (String -> [HtmlAttr] -> [a] -> a)
       -> (String -> a)
       -> Html
       -> a
-foldHtml f g (HtmlTag str attr fmls) 
-      = f str attr (map (foldHtml f g) fmls) 
-foldHtml f g (HtmlString  str)           
+foldHtml f g (HtmlTag str attr fmls)
+      = f str attr (map (foldHtml f g) fmls)
+foldHtml f g (HtmlString  str)
       = g str
 
 -}
@@ -202,8 +202,8 @@
       fixChar c = "&#" ++ show (ord c) ++ ";"
 
 
--- | This is not processed for special chars. 
--- use stringToHtml or lineToHtml instead, for user strings, 
+-- | This is not processed for special chars.
+-- use stringToHtml or lineToHtml instead, for user strings,
 -- because they understand special chars, like @'<'@.
 primHtml :: String -> Html
 primHtml x | null x    = Html []
@@ -211,7 +211,7 @@
 
 
 
--- 
+--
 -- * Html Rendering
 --
 
@@ -221,53 +221,53 @@
 -- | Output the HTML without adding newlines or spaces within the markup.
 --   This should be the most time and space efficient way to
 --   render HTML, though the ouput is quite unreadable.
-showHtmlInternal :: HTML html => 
+showHtmlInternal :: HTML html =>
                     String -- ^ DOCTYPE declaration
                  -> html -> String
-showHtmlInternal docType theHtml = 
+showHtmlInternal docType theHtml =
     docType ++ showHtmlFragment (mkHtml theHtml)
 
 -- | Outputs indented HTML. Because space matters in
 --   HTML, the output is quite messy.
-renderHtmlInternal :: HTML html => 
+renderHtmlInternal :: HTML html =>
                       String  -- ^ DOCTYPE declaration
                    -> html -> String
 renderHtmlInternal docType theHtml =
       docType ++ "\n" ++ renderHtmlFragment (mkHtml theHtml) ++ "\n"
 
 -- | Outputs indented HTML, with indentation inside elements.
---   This can change the meaning of the HTML document, and 
+--   This can change the meaning of the HTML document, and
 --   is mostly useful for debugging the HTML output.
 --   The implementation is inefficient, and you are normally
 --   better off using 'showHtml' or 'renderHtml'.
-prettyHtmlInternal :: HTML html => 
+prettyHtmlInternal :: HTML html =>
                       String -- ^ DOCTYPE declaration
                    -> html -> String
-prettyHtmlInternal docType theHtml = 
+prettyHtmlInternal docType theHtml =
     docType ++ "\n" ++ prettyHtmlFragment (mkHtml theHtml)
 
 -- | Render a piece of HTML without adding a DOCTYPE declaration
 --   or root element. Does not add any extra whitespace.
 showHtmlFragment :: HTML html => html -> String
-showHtmlFragment h = 
+showHtmlFragment h =
     (foldr (.) id $ map showHtml' $ getHtmlElements $ toHtml h) ""
 
 -- | Render a piece of indented HTML without adding a DOCTYPE declaration
 --   or root element. Only adds whitespace where it does not change
 --   the meaning of the document.
 renderHtmlFragment :: HTML html => html -> String
-renderHtmlFragment h = 
+renderHtmlFragment h =
     (foldr (.) id $ map (renderHtml' 0) $ getHtmlElements $ toHtml h) ""
 
--- | Render a piece of indented HTML without adding a DOCTYPE declaration 
+-- | Render a piece of indented HTML without adding a DOCTYPE declaration
 --   or a root element.
 --   The indentation is done inside elements.
---   This can change the meaning of the HTML document, and 
+--   This can change the meaning of the HTML document, and
 --   is mostly useful for debugging the HTML output.
 --   The implementation is inefficient, and you are normally
 --   better off using 'showHtmlFragment' or 'renderHtmlFragment'.
 prettyHtmlFragment :: HTML html => html -> String
-prettyHtmlFragment = 
+prettyHtmlFragment =
     unlines . concat . map prettyHtml' . getHtmlElements . toHtml
 
 -- | Show a single HTML element, without adding whitespace.
@@ -305,10 +305,10 @@
                 markupContent = html,
                 markupAttrs = attrs })
       = if isNoHtml html && elem name validHtmlITags
-        then 
+        then
          [rmNL (renderTag True name attrs "" "")]
         else
-         [rmNL (renderTag False name attrs "" "")] ++ 
+         [rmNL (renderTag False name attrs "" "")] ++
           shift (concat (map prettyHtml' (getHtmlElements html))) ++
          [rmNL (renderEndTag name "" "")]
   where
@@ -318,10 +318,10 @@
 
 -- | Show a start tag
 renderTag :: Bool       -- ^ 'True' if the empty tag shorthand should be used
-	  -> String     -- ^ Tag name
-	  -> [HtmlAttr] -- ^ Attributes
-	  -> String     -- ^ Whitespace to add after attributes
-	  -> ShowS
+          -> String     -- ^ Tag name
+          -> [HtmlAttr] -- ^ Attributes
+          -> String     -- ^ Whitespace to add after attributes
+          -> ShowS
 renderTag empty name attrs nl r
       = "<" ++ name ++ shownAttrs ++ nl ++ close ++ r
   where
@@ -335,8 +335,8 @@
 
 -- | Show an end tag
 renderEndTag :: String -- ^ Tag name
-	     -> String -- ^ Whitespace to add after tag name
-	     -> ShowS
+             -> String -- ^ Whitespace to add after tag name
+             -> ShowS
 renderEndTag name nl r = "</" ++ name ++ nl ++ ">" ++ r
 
 
@@ -344,17 +344,17 @@
 --   short-hand.
 validHtmlITags :: [String]
 validHtmlITags = [
-		  "area",
-		  "base",
-		  "basefont",
-		  "br",
+                  "area",
+                  "base",
+                  "basefont",
+                  "br",
                   "col",
                   "frame",
-		  "hr",
-		  "img",
-		  "input",
+                  "hr",
+                  "img",
+                  "input",
                   "isindex",
                   "link",
-		  "meta",
-		  "param"
-		 ]
+                  "meta",
+                  "param"
+                 ]
diff --git a/Text/XHtml/Strict.hs b/Text/XHtml/Strict.hs
--- a/Text/XHtml/Strict.hs
+++ b/Text/XHtml/Strict.hs
@@ -1,7 +1,3 @@
-#if __GLASGOW_HASKELL__ >= 701
-{-# LANGUAGE Safe #-}
-#endif
-
 -- | Produces XHTML 1.0 Strict.
 module Text.XHtml.Strict (
      -- * Data types
diff --git a/Text/XHtml/Strict/Attributes.hs b/Text/XHtml/Strict/Attributes.hs
--- a/Text/XHtml/Strict/Attributes.hs
+++ b/Text/XHtml/Strict/Attributes.hs
@@ -1,8 +1,4 @@
 {-# OPTIONS_HADDOCK hide #-}
--- #hide
-#if __GLASGOW_HASKELL__ >= 701
-{-# LANGUAGE Safe #-}
-#endif
 
 module Text.XHtml.Strict.Attributes where
 
diff --git a/Text/XHtml/Strict/Elements.hs b/Text/XHtml/Strict/Elements.hs
--- a/Text/XHtml/Strict/Elements.hs
+++ b/Text/XHtml/Strict/Elements.hs
@@ -1,8 +1,4 @@
 {-# OPTIONS_HADDOCK hide #-}
--- #hide
-#if __GLASGOW_HASKELL__ >= 701
-{-# LANGUAGE Safe #-}
-#endif
 
 module Text.XHtml.Strict.Elements where
 
diff --git a/Text/XHtml/Table.hs b/Text/XHtml/Table.hs
--- a/Text/XHtml/Table.hs
+++ b/Text/XHtml/Table.hs
@@ -1,8 +1,3 @@
-{-# LANGUAGE CPP #-}
-#if __GLASGOW_HASKELL__ >= 701
-{-# LANGUAGE Safe #-}
-#endif
-
 -- | Table combinators for XHTML.
 module Text.XHtml.Table (HtmlTable, HTMLTABLE(..),
                         (</>), above, (<->), beside, 
diff --git a/Text/XHtml/Transitional.hs b/Text/XHtml/Transitional.hs
--- a/Text/XHtml/Transitional.hs
+++ b/Text/XHtml/Transitional.hs
@@ -1,7 +1,3 @@
-#if __GLASGOW_HASKELL__ >= 701
-{-# LANGUAGE Safe #-}
-#endif
-
 -- | Produces XHTML 1.0 Transitional.
 module Text.XHtml.Transitional (
      -- * Data types
diff --git a/Text/XHtml/Transitional/Attributes.hs b/Text/XHtml/Transitional/Attributes.hs
--- a/Text/XHtml/Transitional/Attributes.hs
+++ b/Text/XHtml/Transitional/Attributes.hs
@@ -1,8 +1,4 @@
 {-# OPTIONS_HADDOCK hide #-}
--- #hide
-#if __GLASGOW_HASKELL__ >= 701
-{-# LANGUAGE Safe #-}
-#endif
 
 module Text.XHtml.Transitional.Attributes where
 
diff --git a/Text/XHtml/Transitional/Elements.hs b/Text/XHtml/Transitional/Elements.hs
--- a/Text/XHtml/Transitional/Elements.hs
+++ b/Text/XHtml/Transitional/Elements.hs
@@ -1,8 +1,4 @@
 {-# OPTIONS_HADDOCK hide #-}
--- #hide
-#if __GLASGOW_HASKELL__ >= 701
-{-# LANGUAGE Safe #-}
-#endif
 
 module Text.XHtml.Transitional.Elements where
 
diff --git a/xhtml.cabal b/xhtml.cabal
--- a/xhtml.cabal
+++ b/xhtml.cabal
@@ -1,5 +1,5 @@
 Name:               xhtml
-Version:            3000.2.1
+Version:            3000.2.2
 Copyright:          Bjorn Bringert 2004-2006, Andy Gill and the Oregon
                     Graduate Institute of Science and Technology, 1999-2001
 Maintainer:         Chris Dornan <chris@chrisdornan.com>
@@ -13,17 +13,36 @@
 Stability:          Stable
 Category:           Web, XML, Pretty Printer
 Homepage:           https://github.com/haskell/xhtml
+Bug-Reports:        https://github.com/haskell/xhtml/issues
 Build-type:         Simple
-Cabal-version:      >= 1.6
+Cabal-version:      >= 1.10
+extra-source-files: ChangeLog.md
 
 Source-repository head
     type:           git
     location:       https://github.com/haskell/xhtml
 
-library 
-    Build-depends:  base >= 4.0 && < 5.0
-    Exposed-modules: 
-                    Text.XHtml, 
+library
+    Default-Language: Haskell2010
+    if impl(ghc >= 7.2)
+        Default-Extensions: Safe
+
+    Build-depends: base >= 4 && < 5
+    if impl(ghc >= 8.0)
+        -- Enable warnings about potential future incompatibilities
+        ghc-options: -Wcompat -Wnoncanonical-monadfail-instances -Wnoncanonical-monad-instances
+    else
+        -- This provides compatibility with versions prior to GHC 8.0 / base-4.9, when `Data.Semigroup`
+        -- still lived in `semigroups`.
+
+        -- Note: semigroups-0.8 is a reasonably early version depending only on base & containers,
+        --       and `xhtml` only needs to define the class instance
+        --       so we can easily support a wide range of major
+        --       versions of `semigroups`
+        Build-depends: semigroups >= 0.8 && < 0.19
+
+    Exposed-modules:
+                    Text.XHtml,
                     Text.XHtml.Frameset,
                     Text.XHtml.Strict,
                     Text.XHtml.Transitional,
@@ -39,6 +58,5 @@
                     Text.XHtml.BlockTable,
                     Text.XHtml.Extras,
                     Text.XHtml.Internals
-    
-    ghc-options:    -Wall
-    Extensions:     CPP
+
+    ghc-options:    -Wall -fwarn-tabs
