diff --git a/rdf4h.cabal b/rdf4h.cabal
--- a/rdf4h.cabal
+++ b/rdf4h.cabal
@@ -1,5 +1,5 @@
 name:            rdf4h
-version:         5.0.1
+version:         5.1.0
 synopsis:        A library for RDF processing in Haskell
 description:
   'RDF for Haskell' is a library for working with RDF in Haskell.
@@ -10,8 +10,8 @@
   also supports IRI parsing and resolution, and compiled-time
   generation of Haskell modules from Turtle schema files.
 
-author:          Rob Stewart, Pierre Le Marre, Slava Kravchenko, Calvin Smith,  Fabian Meyer
-copyright:       (c) Rob Stewart, Pierre Le Marre, Slava Kravchenko, Calvin Smith, Renzo Carbonara, Fabian Meyer
+author:          Rob Stewart, Pierre Le Marre, Slava Kravchenko, Calvin Smith, Fabian Meyer, koslambrou, Tim McIver 
+copyright:       (c) Rob Stewart, Calvin Smith
 maintainer:      Rob Stewart <robstewart57@gmail.com>
 homepage:        https://github.com/robstewart57/rdf4h
 bug-reports:     https://github.com/robstewart57/rdf4h/issues
@@ -21,7 +21,7 @@
 build-type:      Simple
 category:        RDF
 stability:       stable
-tested-with:     GHC==8.0.2, GHC==8.2.2, GHC==8.4.3, GHC==8.6.5, GHC==8.8.3
+tested-with:     GHC==9.2.5
 extra-tmp-files: test
 extra-source-files: examples/ParseURLs.hs
                   , examples/ESWC.hs
@@ -97,9 +97,8 @@
                  , selective
                  , html-entities
                  , xeno
-                 , template-haskell
+                 , template-haskell >= 2.18.0
   other-modules:   Text.RDF.RDF4H.XmlParser.Xmlbf
-                 , Text.RDF.RDF4H.XmlParser.Xeno
                  , Text.RDF.RDF4H.XmlParser.Xeno
   if impl(ghc < 7.6)
     build-depends: ghc-prim
diff --git a/src/Data/RDF/Vocabulary/Generator/VocabularyGenerator.hs b/src/Data/RDF/Vocabulary/Generator/VocabularyGenerator.hs
--- a/src/Data/RDF/Vocabulary/Generator/VocabularyGenerator.hs
+++ b/src/Data/RDF/Vocabulary/Generator/VocabularyGenerator.hs
@@ -6,19 +6,23 @@
   )
 where
 
+import Control.Monad (join)
 import Data.Char (isLower)
-import Data.List (nub)
+import Data.List (nub, sortBy)
 import qualified Data.Map as M
 import Data.Maybe (maybeToList)
 import Data.RDF
   ( AdjHashMap,
-    Node (UNode),
+    LValue (..),
+    Node (..),
     PrefixMappings (PrefixMappings),
     RDF,
     Rdf,
     TurtleParser (TurtleParser),
+    objectOf,
     parseFile,
     prefixMappings,
+    query,
     subjectOf,
     triplesOf,
   )
@@ -50,7 +54,7 @@
   -- | the filepath of the file containing the schema in RDF Turtle format.
   String ->
   Q [Dec]
-genVocabulary file = vocabulary <$> runIO (loadGraph file)
+genVocabulary file = runIO (loadGraph file) >>= vocabulary
 
 loadGraph :: String -> IO (RDF AdjHashMap)
 loadGraph file =
@@ -58,21 +62,25 @@
     Left err -> error $ show err
     Right rdfGraph -> return rdfGraph
 
-vocabulary :: Rdf a => RDF a -> [Dec]
+vocabulary :: Rdf a => RDF a -> Q [Dec]
 vocabulary graph =
   let nameDecls = do
         subject <- nub $ subjectOf <$> triplesOf graph
         iri <- maybeToList $ toIRI subject
         name <- maybeToList $ iriToName iri
-        return (name, declareIRI name iri)
+        let comment = combineComments .
+                      sequenceA .
+                      fmap (nodeToComment . objectOf) $
+                      query graph (Just subject) (Just rdfsCommentNode) Nothing
+        return (name, declareIRI name iri comment)
       (PrefixMappings prefixMappings') = prefixMappings graph
       namespaceDecls = do
         (prefix, iri) <- M.toList prefixMappings'
         let name = mkName . T.unpack . escape $ prefix <> "NS"
         return $ declarePrefix name prefix iri
-      iriDecls = snd <$> nameDecls
+      iriDecls = fmap snd . sortBy (\x y -> fst y `compare` fst x) $ nameDecls
       irisDecl = declareIRIs $ fst <$> nameDecls
-   in irisDecl : namespaceDecls <> iriDecls
+   in sequence $ irisDecl : namespaceDecls <> iriDecls
 
 toIRI :: Node -> Maybe Text
 toIRI (UNode iri) = Just iri
@@ -87,24 +95,47 @@
 mkPrefixedNSFun :: Exp
 mkPrefixedNSFun = VarE $ mkName "Data.RDF.Namespace.mkPrefixedNS"
 
-declareIRI :: Name -> Text -> Dec
-declareIRI name iri =
+nodeToComment :: Node -> Maybe Text
+nodeToComment (UNode uri)           = Just $ "See \\<<" <> uri <> ">\\>."
+nodeToComment (BNode _)             = Nothing
+nodeToComment (BNodeGen _)          = Nothing
+nodeToComment (LNode (PlainL l))    = Just l
+nodeToComment (LNode (PlainLL l _)) = Just l
+nodeToComment (LNode (TypedL l _))  = Just l
+
+combineComments :: Maybe [Text] -> Maybe Text
+combineComments = join . fmap combineComments'
+  where
+    combineComments' [] = Nothing
+    combineComments' comments = Just . T.intercalate "\n" $ comments
+
+rdfsCommentNode :: Node
+rdfsCommentNode = UNode "http://www.w3.org/2000/01/rdf-schema#comment"
+
+declareIRI :: Name -> Text -> Maybe Text -> Q Dec
+declareIRI name iri comment =
   let iriLiteral = LitE . StringL $ T.unpack iri
       unodeLiteral = AppE unodeFun $ AppE packFun iriLiteral
-   in FunD name [Clause [] (NormalB unodeLiteral) []]
+   in funD_doc name [return $ Clause [] (NormalB unodeLiteral) []]
+               (T.unpack <$> comment)
+               [Nothing]
 
-declareIRIs :: [Name] -> Dec
+declareIRIs :: [Name] -> Q Dec
 declareIRIs names =
   let iriList = ListE (VarE <$> names)
-   in FunD (mkName "iris") [Clause [] (NormalB iriList) []]
+   in funD_doc (mkName "iris") [return $ Clause [] (NormalB iriList) []]
+               (Just $ "All IRIs in this vocabulary.")
+               [Nothing]
 
 -- namespace = mkPrefixedNS "ogit" "http://www.purl.org/ogit/"
-declarePrefix :: Name -> Text -> Text -> Dec
+declarePrefix :: Name -> Text -> Text -> Q Dec
 declarePrefix name prefix iri =
   let prefixLiteral = AppE packFun . LitE . StringL . T.unpack $ prefix
       iriLiteral = AppE packFun . LitE . StringL . T.unpack $ iri
       namespace = AppE (AppE mkPrefixedNSFun prefixLiteral) iriLiteral
-   in FunD name [Clause [] (NormalB namespace) []]
+   in funD_doc name [return $ Clause [] (NormalB namespace) []]
+               (Just $ "Namespace prefix for \\<<" <> T.unpack iri <> ">\\>.")
+               [Nothing]
 
 iriToName :: Text -> Maybe Name
 iriToName iri = mkName . T.unpack . escape <$> (lastMay . filter (not . T.null) . T.split (`elem` separators)) iri
