diff --git a/cimple.cabal b/cimple.cabal
--- a/cimple.cabal
+++ b/cimple.cabal
@@ -1,5 +1,5 @@
 name:                 cimple
-version:              0.0.6
+version:              0.0.7
 synopsis:             Simple C-like programming language
 homepage:             https://toktok.github.io/
 license:              GPL-3
@@ -32,7 +32,8 @@
     , Language.Cimple.Pretty
     , Language.Cimple.Program
   other-modules:
-      Language.Cimple.AST
+      Language.Cimple.Annot
+    , Language.Cimple.AST
     , Language.Cimple.Flatten
     , Language.Cimple.Graph
     , Language.Cimple.Lexer
diff --git a/src/Language/Cimple.hs b/src/Language/Cimple.hs
--- a/src/Language/Cimple.hs
+++ b/src/Language/Cimple.hs
@@ -7,6 +7,7 @@
 import           Control.Monad.State.Lazy    (State)
 import           Data.Text                   (Text)
 
+import           Language.Cimple.Annot       as X
 import           Language.Cimple.AST         as X
 import           Language.Cimple.Lexer       as X
 import           Language.Cimple.Parser      as X
diff --git a/src/Language/Cimple/AST.hs b/src/Language/Cimple/AST.hs
--- a/src/Language/Cimple/AST.hs
+++ b/src/Language/Cimple/AST.hs
@@ -15,7 +15,8 @@
     , CommentStyle (..)
     ) where
 
-import           Data.Aeson                   (FromJSON, ToJSON)
+import           Data.Aeson                   (FromJSON, FromJSON1, ToJSON,
+                                               ToJSON1)
 import           Data.Fix                     (Fix)
 import           Data.Functor.Classes         (Eq1, Read1, Show1)
 import           Data.Functor.Classes.Generic (FunctorClassesDefault (..))
@@ -114,8 +115,8 @@
 
 type Node lexeme = Fix (NodeF lexeme)
 
-instance (FromJSON lexeme, FromJSON a) => FromJSON (NodeF lexeme a)
-instance (ToJSON lexeme, ToJSON a) => ToJSON (NodeF lexeme a)
+instance FromJSON lexeme => FromJSON1 (NodeF lexeme)
+instance ToJSON lexeme => ToJSON1 (NodeF lexeme)
 
 data AssignOp
     = AopEq
diff --git a/src/Language/Cimple/Annot.hs b/src/Language/Cimple/Annot.hs
new file mode 100644
--- /dev/null
+++ b/src/Language/Cimple/Annot.hs
@@ -0,0 +1,33 @@
+{-# LANGUAGE DeriveFunctor      #-}
+{-# LANGUAGE DeriveGeneric      #-}
+{-# LANGUAGE DeriveTraversable  #-}
+{-# LANGUAGE DerivingVia        #-}
+{-# LANGUAGE FlexibleInstances  #-}
+{-# LANGUAGE StandaloneDeriving #-}
+{-# LANGUAGE StrictData         #-}
+{-# LANGUAGE TypeOperators      #-}
+module Language.Cimple.Annot
+    ( AnnotF (..)
+    , AnnotNode
+    , addAnnot
+    , removeAnnot
+    ) where
+
+import           Data.Fix                     (Fix, hoistFix)
+import           Data.Functor.Classes         (Eq1, Read1, Show1)
+import           Data.Functor.Classes.Generic (FunctorClassesDefault (..))
+import           Data.Functor.Compose         (Compose (..))
+import           GHC.Generics                 (Generic, Generic1)
+import           Language.Cimple.AST          (Node, NodeF)
+
+data AnnotF attr a = Annot { attr :: attr, unAnnot :: a }
+    deriving (Functor, Generic, Generic1)
+    deriving (Show1, Read1, Eq1) via FunctorClassesDefault (AnnotF attr)
+
+type AnnotNode lexeme = Fix (AnnotF () `Compose` NodeF lexeme)
+
+addAnnot :: Node lexeme -> AnnotNode lexeme
+addAnnot = hoistFix $ Compose . Annot ()
+
+removeAnnot :: AnnotNode lexeme -> Node lexeme
+removeAnnot = hoistFix $ unAnnot . getCompose
