diff --git a/Data/Generics/Geniplate.hs b/Data/Generics/Geniplate.hs
--- a/Data/Generics/Geniplate.hs
+++ b/Data/Generics/Geniplate.hs
@@ -80,10 +80,10 @@
 funDef f e = [FunD f [Clause [] (NormalB e) []]]
 
 instDef :: Name -> [Type] -> Name -> Exp -> [Dec]
-#if __GLASGOW_HASKELL__ <= 710
-instDef cls ts met e = [InstanceD [] (foldl AppT (ConT cls) ts) (funDef met e)]
-#else
+#if MIN_VERSION_template_haskell(2,11,0)
 instDef cls ts met e = [InstanceD Nothing [] (foldl AppT (ConT cls) ts) (funDef met e)]
+#else
+instDef cls ts met e = [InstanceD [] (foldl AppT (ConT cls) ts) (funDef met e)]
 #endif
 
 -- | Create a 'TransformBi' instance.
@@ -170,8 +170,8 @@
     x <- newName "_x"
     (ds, tr) <- trBiQ doDescend raMonad stops f ft st
     let e = LamE [VarP f, VarP x] $ LetE ds $ AppE tr (VarE x)
-        cls = case doDescend of MTransformBi -> ''TransformBiM; MDescendBi -> ''DescendBiM; MDescend -> error "MDescend"
-        met = case doDescend of MTransformBi ->  'transformBiM; MDescendBi ->  'descendBiM; MDescend -> error "MDescend"
+        cls = case doDescend of MTransformBi -> ''TransformBiM; MDescendBi -> ''DescendBiM
+        met = case doDescend of MTransformBi ->  'transformBiM; MDescendBi ->  'descendBiM
     return $ instDef cls [mnd, ft, st] met e
 instanceTransformBiMT' _ _ _ t = genError "instanceTransformBiMT: the argument should be of the form [t| (S, T) |]"
 
@@ -196,7 +196,11 @@
 genUniverseBiT' :: [TypeQ] -> TypeQ -> Q Exp
 genUniverseBiT' stops q = q >>= splitType >>= genUniverseBiTsplit stops
 
+#if MIN_VERSION_template_haskell(2,17,0)
+genUniverseBiTsplit :: [TypeQ] -> ([TyVarBndr a], Type, Type) -> Q Exp
+#else
 genUniverseBiTsplit :: [TypeQ] -> ([TyVarBndr], Type, Type) -> Q Exp
+#endif
 genUniverseBiTsplit stops (_tvs,from,tos) = do
     let to = unList tos
 --    qRunIO $ print (from, to)
@@ -213,26 +217,46 @@
     qReport b = lift . qReport b
     qRecover = error "Data.Generics.Geniplate: qRecover not implemented"
     qReify = lift . qReify
-#if __GLASGOW_HASKELL__ >= 704
+#if MIN_VERSION_template_haskell(2,7,0)
     qReifyInstances n = lift . qReifyInstances n
-#elif __GLASGOW_HASKELL__ >= 702
+#elif MIN_VERSION_template_haskell(2,5,0)
     qClassInstances n = lift . qClassInstances n
 #endif
     qLocation = lift qLocation
     qRunIO = lift . qRunIO
-#if __GLASGOW_HASKELL__ >= 706
+#if MIN_VERSION_template_haskell(2,14,0)
+    qAddForeignFilePath l = undefined -- lift . qAddForeignFilePath l
+#elif MIN_VERSION_template_haskell(2,12,0)
+    qAddForeignFile l   = undefined -- lift . qAddForeignFile l
+#endif
+#if MIN_VERSION_template_haskell(2,7,0)
     qLookupName ns = lift . qLookupName ns
     qAddDependentFile = lift . qAddDependentFile
-#if __GLASGOW_HASKELL__ >= 708
+#if MIN_VERSION_template_haskell(2,9,0)
     qReifyRoles = lift . qReifyRoles
     qReifyAnnotations = lift . qReifyAnnotations
     qReifyModule = lift . qReifyModule
     qAddTopDecls = lift . qAddTopDecls
     qAddModFinalizer = lift . qAddModFinalizer
-    qGetQ = undefined -- lift . qGetQ
+    qGetQ = lift qGetQ
     qPutQ = lift . qPutQ
+#if MIN_VERSION_template_haskell(2,11,0)
+    qReifyFixity        = undefined -- lift . qReifyFixity
+    qReifyConStrictness = undefined -- lift . qReifyConStrictness
+    qIsExtEnabled       = undefined -- lift . qIsExtEnabled
+    qExtsEnabled        = undefined -- lift (qExtsEnabled)
+#if MIN_VERSION_template_haskell(2,13,0)
+    qAddCorePlugin      = undefined -- lift . qAddCorePlugin
+#if MIN_VERSION_template_haskell(2,14,0)
+    qAddTempFile        = undefined -- lift . qAddTempFile
+#if MIN_VERSION_template_haskell(2,16,0)
+    qReifyType          = undefined -- lift . qReifyType
 #endif
 #endif
+#endif
+#endif
+#endif
+#endif
 
 uniBiQ :: [TypeQ] -> Type -> Type -> Q ([Dec], Exp)
 uniBiQ stops from ato = do
@@ -382,11 +406,20 @@
 
 type Subst = [(Name, Type)]
 
+#if MIN_VERSION_template_haskell(2,17,0)
+mkSubst :: [TyVarBndr a] -> [Type] -> Subst
+#else
 mkSubst :: [TyVarBndr] -> [Type] -> Subst
+#endif
 mkSubst vs ts =
    let vs' = map un vs
+#if MIN_VERSION_template_haskell(2,17,0)
+       un (PlainTV v _) = v
+       un (KindedTV v _ _) = v
+#else
        un (PlainTV v) = v
        un (KindedTV v _) = v
+#endif
    in  assert (length vs' == length ts) $ zip vs' ts
 
 subst :: Subst -> Type -> Type
@@ -396,21 +429,29 @@
 subst s (SigT t k) = SigT (subst s t) k
 subst _ t = t
 
+#if MIN_VERSION_template_haskell(2,17,0)
+getTyConInfo :: (Quasi q) => Name -> q ([TyVarBndr ()], [Con])
+#else
 getTyConInfo :: (Quasi q) => Name -> q ([TyVarBndr], [Con])
+#endif
 getTyConInfo con = do
     info <- qReify con
     case info of
-#if __GLASGOW_HASKELL__ <= 710
-        TyConI (DataD _ _ tvs cs _)   -> return (tvs, cs)
-        TyConI (NewtypeD _ _ tvs c _) -> return (tvs, [c])
-#else
+#if MIN_VERSION_template_haskell(2,11,0)
         TyConI (DataD _ _ tvs _ cs _)   -> return (tvs, cs)
         TyConI (NewtypeD _ _ tvs _ c _) -> return (tvs, [c])
+#else
+        TyConI (DataD _ _ tvs cs _)   -> return (tvs, cs)
+        TyConI (NewtypeD _ _ tvs c _) -> return (tvs, [c])
 #endif
         PrimTyConI{} -> return ([], [])
         i -> genError $ "unexpected TyCon: " ++ show i
 
+#if MIN_VERSION_template_haskell(2,17,0)
+splitType :: (Quasi q) => Type -> q ([TyVarBndr Specificity], Type, Type)
+#else
 splitType :: (Quasi q) => Type -> q ([TyVarBndr], Type, Type)
+#endif
 splitType t =
   case t of
     (ForallT tvs _ t) -> do
@@ -420,14 +461,18 @@
     _ -> genError $ "Type is not an arrow: " ++ pprint t
 
 
+#if MIN_VERSION_template_haskell(2,17,0)
+getNameType :: (Quasi q) => Name -> q ([TyVarBndr Specificity], Type, Type)
+#else
 getNameType :: (Quasi q) => Name -> q ([TyVarBndr], Type, Type)
+#endif
 getNameType name = do
     info <- qReify name
     case info of
-#if __GLASGOW_HASKELL__ <= 710
-        VarI _ t _ _ -> splitType t
-#else
+#if MIN_VERSION_template_haskell(2,11,0)
         VarI _ t _  -> splitType t
+#else
+        VarI _ t _ _ -> splitType t
 #endif
         _ -> genError $ "Name is not variable: " ++ pprint name
 
@@ -611,8 +656,7 @@
 trBiTuple :: Bool -> Mode -> RetAp -> Exp -> Type -> Type -> [Type] -> U [Clause]
 trBiTuple seenStop doDescend ra f ft st ts = do
     vs <- mapM (const $ qNewName "_t") ts
-#if __GLASGOW_HASKELL__ >= 810
--- `TupE` handles tuple sections since template-haskell 2.16.
+#if MIN_VERSION_template_haskell(2,16,0)
     let tupE = LamE (map VarP vs) $ TupE (map (Just . VarE) vs)
 #else
     let tupE = LamE (map VarP vs) $ TupE (map VarE vs)
diff --git a/changelog b/changelog
--- a/changelog
+++ b/changelog
@@ -1,3 +1,6 @@
+geniplate 0.7.8 (released 2020-06-18):
+* Support GHC 9.0.1
+
 geniplate 0.7.7 (released 2020-04-01):
 * Support GHC 8.10.1
 
diff --git a/geniplate-mirror.cabal b/geniplate-mirror.cabal
--- a/geniplate-mirror.cabal
+++ b/geniplate-mirror.cabal
@@ -1,5 +1,5 @@
 Name:           geniplate-mirror
-Version:        0.7.7
+Version:        0.7.8
 Synopsis:       Use Template Haskell to generate Uniplate-like functions.
 Description:    Use Template Haskell to generate Uniplate-like functions.
                 .
@@ -14,8 +14,8 @@
 Maintainer:     Dan Rosén <dan.rosen@gu.se>, Liang-Ting Chen <liang.ting.chen.tw@gmail.com>
 Copyright:      2014-2015 Lennart Augustsson
 Category:       Generics
+Cabal-Version:  >= 1.10
 Build-type:     Simple
-Cabal-Version:  >= 1.8
 Stability:      experimental
 
 Extra-source-files:
@@ -28,6 +28,7 @@
   location: https://github.com/danr/geniplate
 
 library
-  Build-Depends: base >= 4 && < 5.0, template-haskell < 2.17, mtl
+  Default-Language: Haskell98
+  Build-Depends: base >= 4 && < 5.0, template-haskell < 2.18, mtl
 
   Exposed-modules:      Data.Generics.Geniplate
