diff --git a/ChangeLog.md b/ChangeLog.md
--- a/ChangeLog.md
+++ b/ChangeLog.md
@@ -1,5 +1,9 @@
 # Revision history for aeson-gadt-th
 
+## 0.2.1.2
+
+* Add version bounds to cabal file
+
 ## 0.2.1.1
 
 * Drop markdown-unlit in favor of "Bird"-style LHS to avoid some cross-compilation issues.
diff --git a/aeson-gadt-th.cabal b/aeson-gadt-th.cabal
--- a/aeson-gadt-th.cabal
+++ b/aeson-gadt-th.cabal
@@ -1,6 +1,6 @@
-cabal-version: >=2.0
+cabal-version: 2.0
 name: aeson-gadt-th
-version: 0.2.1.1
+version: 0.2.1.2
 synopsis: Derivation of Aeson instances for GADTs
 category: JSON
 description: Template Haskell for generating ToJSON and FromJSON instances for GADTs. See <https://github.com/obsidiansystems/aeson-gadt-th/blob/master/README.md README.md> for examples.
@@ -10,26 +10,33 @@
 maintainer: maintainer@obsidian.systems
 copyright: 2019 Obsidian Systems LLC
 build-type: Simple
+tested-with:
+  GHC  ==8.0.2 || ==8.2.2 || ==8.4.4 || ==8.6.5
 extra-source-files: README.md
                     ChangeLog.md
 
+flag build-readme
+  default: True
+
 library
   exposed-modules: Data.Aeson.GADT.TH
   build-depends: base >= 4.8 && < 4.13
-               , aeson
-               , containers
-               , dependent-sum
-               , transformers
-               , template-haskell
+               , aeson >= 1.4 && < 1.5
+               , containers >= 0.5 && < 0.7
+               , dependent-sum >= 0.6.2 && < 0.7
+               , transformers >= 0.5 && < 0.6
+               , template-haskell >= 2.11.0 && < 2.15
   hs-source-dirs: src
   default-language: Haskell2010
 
 executable readme
+  if !flag(build-readme)
+    buildable: False
   build-depends: base
                , aeson
                , dependent-sum
-               , dependent-sum-template
-               , dependent-map
+               , dependent-sum-template >= 0.1 && < 0.2
+               , dependent-map >= 0.3 && < 0.4
                , aeson-gadt-th
   default-language: Haskell2010
   main-is: README.lhs
diff --git a/src/Data/Aeson/GADT/TH.hs b/src/Data/Aeson/GADT/TH.hs
--- a/src/Data/Aeson/GADT/TH.hs
+++ b/src/Data/Aeson/GADT/TH.hs
@@ -1,4 +1,5 @@
 {-# LANGUAGE ConstraintKinds #-}
+{-# LANGUAGE CPP #-}
 {-# LANGUAGE ExistentialQuantification #-}
 {-# LANGUAGE FlexibleContexts #-}
 {-# LANGUAGE FlexibleInstances #-}
@@ -96,8 +97,8 @@
   wildName <- newName "s"
   let wild = match (varP wildName) (normalB [e|
         fail $
-          "Expected tag to be one of [" <> allConNames <> "] but got: "
-          <> $(varE wildName)
+          "Expected tag to be one of [" ++ allConNames ++ "] but got: "
+          ++ $(varE wildName)
         |]) []
   topVars <- init <$> makeTopVars n
   let n' = foldl (\c v -> AppT c (VarT v)) (ConT n) topVars
@@ -199,7 +200,9 @@
       ConT n -> ConT n
       TupleT k -> TupleT k
       UnboxedTupleT k -> UnboxedTupleT k
+#if MIN_VERSION_template_haskell(2,12,0)
       UnboxedSumT k -> UnboxedSumT k
+#endif
       ArrowT -> ArrowT
       EqualityT -> EqualityT
       ListT -> ListT
@@ -212,8 +215,8 @@
       WildCardT -> WildCardT
     findVar v (tv:_) (AppT _ (VarT v')) | v == v' = tv
     findVar v (_:tvs) (AppT t (VarT _)) = findVar v tvs t
-    findVar v _ _ = error $ "substVarsWith: couldn't look up variable substitution for " <> show v
-      <> " with topVars: " <> show topVars <> " resultType: " <> show resultType <> " argType: " <> show argType
+    findVar v _ _ = error $ "substVarsWith: couldn't look up variable substitution for " ++ show v
+      ++ " with topVars: " ++ show topVars ++ " resultType: " ++ show resultType ++ " argType: " ++ show argType
 
 -- | Determine the 'Name' being bound by a 'TyVarBndr'.
 tyVarBndrName :: TyVarBndr -> Name
@@ -244,7 +247,7 @@
 tyConArity' n = reify n >>= return . \case
   TyConI (DataD _ _ ts mk _ _) -> (ts, fromMaybe 0 (fmap kindArity mk))
   TyConI (NewtypeD _ _ ts mk _ _) -> (ts, fromMaybe 0 (fmap kindArity mk))
-  _ -> error $ "tyConArity': Supplied name reified to something other than a data declaration: " <> show n
+  _ -> error $ "tyConArity': Supplied name reified to something other than a data declaration: " ++ show n
 
 -- | Determine the constructors bound by a data or newtype declaration. Errors out if supplied with another
 -- sort of declaration.
diff --git a/test/Expectations.hs b/test/Expectations.hs
--- a/test/Expectations.hs
+++ b/test/Expectations.hs
@@ -15,7 +15,7 @@
   try (evaluate $ f a) >>= \case
     Right b -> pure b
     Left (e :: PatternMatchFail) ->
-      throwHUnit $ "Pattern match failed, value was: " <> show a
+      throwHUnit $ "Pattern match failed, value was: " ++ show a
 
 -- | Same as 'expectPattern' but with its arguments flipped.
 shouldMatchPattern :: (HasCallStack, Show a) => a -> (a -> b) -> IO b
