diff --git a/src/Gargantext/Components/FacetsTable.purs b/src/Gargantext/Components/FacetsTable.purs
index bc017aa4c545592710e4d05fb381682b9b49da4b..a4b3ac516606428e199537e831bbd37347414836 100644
--- a/src/Gargantext/Components/FacetsTable.purs
+++ b/src/Gargantext/Components/FacetsTable.purs
@@ -3,9 +3,6 @@
 --       has not been ported to this module yet.
 module Gargantext.Components.FacetsTable where
 
-import Prelude
-  ( class Eq, class Show, Unit, bind, const, discard, identity, mempty, not
-  , otherwise, pure, unit, void, ($), (*>), (<$>), (<<<), (<>), (==), (>) )
 import Data.Argonaut (class EncodeJson, jsonEmptyObject, (:=), (~>))
 import Data.Generic.Rep (class Generic)
 import Data.Generic.Rep.Eq (genericEq)
@@ -23,6 +20,8 @@ import Reactix as R
 import Reactix.DOM.HTML as H
 import Toestand as T
 
+import Gargantext.Prelude
+
 import Gargantext.Components.Category (CategoryQuery(..), putCategories)
 import Gargantext.Components.Category.Types (Category(..), decodeCategory, favCategory)
 import Gargantext.Components.Search
@@ -106,15 +105,18 @@ newtype ContactsView =
   , annuaireId :: Int
   , delete     :: Boolean
   }
-
 derive instance genericContactsView :: Generic ContactsView _
-
+instance eqContactsView :: Eq ContactsView where
+  eq = genericEq
 instance showContactsView :: Show ContactsView where
   show = genericShow
 
 ----------------------------------------------------------------------
 data Rows = Docs     { docs     :: Seq DocumentsView }
           | Contacts { contacts :: Seq ContactsView  }
+derive instance genericRows :: Generic Rows _
+instance eqRows :: Eq Rows where
+  eq = genericEq
 
 ----------------------------------------------------------------------
 
diff --git a/src/Gargantext/Components/Forest/Tree/Node/Tools/FTree.purs b/src/Gargantext/Components/Forest/Tree/Node/Tools/FTree.purs
index 250cc2df3374d5f3acc44a2c3884add3b7f2c0f7..e06bdf3bbca20732bdaee296d03bc49c54f145f9 100644
--- a/src/Gargantext/Components/Forest/Tree/Node/Tools/FTree.purs
+++ b/src/Gargantext/Components/Forest/Tree/Node/Tools/FTree.purs
@@ -1,10 +1,14 @@
 module Gargantext.Components.Forest.Tree.Node.Tools.FTree where
 
-import Data.Maybe (Maybe(..))
 import Data.Argonaut (class DecodeJson, decodeJson, (.:))
+import Data.Generic.Rep (class Generic)
+import Data.Generic.Rep.Eq (genericEq)
+import Data.Maybe (Maybe(..))
 import Data.Newtype (class Newtype)
+
+import Gargantext.Prelude
+
 import Gargantext.Types  as GT
-import Prelude hiding (div)
 
 -----------------------------------------------------------------------
 type ID   = Int
@@ -12,8 +16,11 @@ type Name = String
 -----------------------------------------------------------------------
 type FTree = NTree LNode
 data NTree a = NTree a (Array (NTree a))
+derive instance genericNTree :: Generic (NTree a) _
+instance eqNTree :: Eq a => Eq (NTree a) where
+  eq (NTree a1 as1) (NTree a2 as2) = (eq a1 a2) && (eq as1 as2)
 type Tree = { tree       :: FTree
-            , tasks :: Array GT.AsyncTaskWithType
+            , tasks     :: Array GT.AsyncTaskWithType
             }
 
 fTreeID :: FTree -> ID
@@ -29,9 +36,10 @@ newtype LNode =
   , nodeType  :: GT.NodeType
   , parent_id :: Maybe ID
   }
-
 derive instance newtypeLNode :: Newtype LNode _
-
+derive instance genericLNode :: Generic LNode _
+instance eqLNode :: Eq LNode where
+  eq = genericEq
 instance decodeJsonLNode :: DecodeJson LNode where
   decodeJson json = do
     obj  <- decodeJson json
diff --git a/src/Gargantext/Components/GraphExplorer/Types.purs b/src/Gargantext/Components/GraphExplorer/Types.purs
index 59cf820cca1d1d155d1477324b78090ed8dcb685..668b329f7418f1d5cae1e476d020f96273050adc 100644
--- a/src/Gargantext/Components/GraphExplorer/Types.purs
+++ b/src/Gargantext/Components/GraphExplorer/Types.purs
@@ -65,6 +65,9 @@ newtype GraphSideCorpus = GraphSideCorpus
   , corpusLabel :: CorpusLabel
   , listId      :: ListId
   }
+derive instance genericGraphSideCorpus :: Generic GraphSideCorpus _
+instance eqGraphSideCorpus :: Eq GraphSideCorpus where
+  eq = genericEq
 
 newtype GraphData = GraphData
   { nodes :: Array Node
@@ -72,8 +75,10 @@ newtype GraphData = GraphData
   , sides :: Array GraphSideCorpus
   , metaData :: Maybe MetaData
   }
-
 derive instance newtypeGraphData :: Newtype GraphData _
+derive instance genericGraphData :: Generic GraphData _
+instance eqGraphData :: Eq GraphData where
+  eq = genericEq
 
 
 newtype MetaData = MetaData
@@ -86,6 +91,9 @@ newtype MetaData = MetaData
   , startForceAtlas :: Boolean
   , title    :: String
   }
+derive instance genericMetaData :: Generic MetaData _
+instance eqMetaData :: Eq MetaData where
+  eq = genericEq
 
 getLegend :: GraphData -> Maybe (Array Legend)
 getLegend (GraphData {metaData}) = (\(MetaData m) -> m.legend) <$> metaData
@@ -291,7 +299,9 @@ newtype Camera =
          , x     :: Number
          , y     :: Number
          }
-
+derive instance genericCamera :: Generic Camera _
+instance eqCamera :: Eq Camera where
+  eq = genericEq
 instance decodeCamera :: DecodeJson Camera where
   decodeJson json = do
     obj   <- decodeJson json
@@ -299,7 +309,6 @@ instance decodeCamera :: DecodeJson Camera where
     x     <- obj .: "x"
     y     <- obj .: "y"
     pure $ Camera { ratio, x, y }
-
 instance jsonEncodeCamera :: EncodeJson Camera where
   encodeJson (Camera c) =
        "ratio" := c.ratio
@@ -312,14 +321,15 @@ newtype HyperdataGraph = HyperdataGraph {
     graph   :: GraphData
   , mCamera :: Maybe Camera
   }
-
+derive instance genericHyperdataGraph :: Generic HyperdataGraph _
+instance eqHyperdataGraph :: Eq HyperdataGraph where
+  eq = genericEq
 instance decodeHyperdataGraph :: DecodeJson HyperdataGraph where
   decodeJson json = do
     obj <- decodeJson json
     graph   <- obj .: "graph"
     mCamera <- obj .:? "camera"
     pure $ HyperdataGraph { graph, mCamera }
-
 instance jsonEncodeHyperdataGraph :: EncodeJson HyperdataGraph where
   encodeJson (HyperdataGraph c) =
       "camera"  := c.mCamera
diff --git a/src/Gargantext/Components/NgramsTable/Core.purs b/src/Gargantext/Components/NgramsTable/Core.purs
index 4338c1df040b91ce732291649a10702904b96e92..1b2a8e1c1629eeae2333d5912ec25b6230d75a6b 100644
--- a/src/Gargantext/Components/NgramsTable/Core.purs
+++ b/src/Gargantext/Components/NgramsTable/Core.purs
@@ -78,7 +78,6 @@ module Gargantext.Components.NgramsTable.Core
   )
   where
 
-import Gargantext.Prelude
 import Control.Monad.State (class MonadState, execState)
 import Data.Argonaut (class DecodeJson, class EncodeJson, decodeJson, encodeJson, jsonEmptyObject, (.:), (.:!), (.:?), (:=), (:=?), (~>), (~>?))
 import Data.Argonaut.Decode.Error (JsonDecodeError(..))
@@ -133,6 +132,8 @@ import Partial (crashWith)
 import Partial.Unsafe (unsafePartial)
 import Toestand as T
 
+import Gargantext.Prelude
+
 import Gargantext.AsyncTasks as GAT
 import Gargantext.Components.Table       as T
 import Gargantext.Components.Table.Types as T
@@ -156,13 +157,14 @@ newtype Versioned a = Versioned
   { version :: Version
   , data    :: a
   }
-
+derive instance genericVersioned :: Generic (Versioned a) _
+instance eqVersioned :: Eq a => Eq (Versioned a) where
+  eq = genericEq
 instance encodeJsonVersioned :: EncodeJson a => EncodeJson (Versioned a) where
   encodeJson (Versioned {version, data: data_})
      = "version" := version
     ~> "data" := data_
     ~> jsonEmptyObject
-
 instance decodeJsonVersioned :: DecodeJson a => DecodeJson (Versioned a) where
   decodeJson json = do
     obj     <- decodeJson json
@@ -177,7 +179,9 @@ newtype VersionedWithCount a = VersionedWithCount
   , count   :: Count
   , data    :: a
   }
-
+derive instance genericVersionedWithCount :: Generic (VersionedWithCount a) _
+instance eqVersionedWithCount :: Eq a => Eq (VersionedWithCount a) where
+  eq = genericEq
 instance encodeJsonVersionedWithCount :: EncodeJson a => EncodeJson (VersionedWithCount a) where
   encodeJson (VersionedWithCount {count, version, data: data_})
      = "version" := version
diff --git a/src/Gargantext/Components/Node.purs b/src/Gargantext/Components/Node.purs
index 3d81d75e04858f67e65ccbdae85c18f1c169bd13..e217fa70273306f7a4d097886b11816f2e2b0062 100644
--- a/src/Gargantext/Components/Node.purs
+++ b/src/Gargantext/Components/Node.purs
@@ -1,8 +1,11 @@
 module Gargantext.Components.Node 
   where
 
-import Gargantext.Prelude
 import Data.Argonaut (class DecodeJson, decodeJson, (.:), (.:?), (.!=))
+import Data.Generic.Rep (class Generic)
+import Data.Generic.Rep.Eq (genericEq)
+
+import Gargantext.Prelude
 
 newtype NodePoly a =
   NodePoly { id :: Int
@@ -13,8 +16,9 @@ newtype NodePoly a =
            , date      :: String
            , hyperdata :: a
            }
-
-
+derive instance genericNodePoly :: Generic (NodePoly a) _
+instance eqNodePoly :: Eq a => Eq (NodePoly a) where
+  eq = genericEq
 instance decodeNodePoly :: (DecodeJson a)
   => DecodeJson (NodePoly a) where
   decodeJson json = do
diff --git a/src/Gargantext/Components/Nodes/Annuaire.purs b/src/Gargantext/Components/Nodes/Annuaire.purs
index 33885abc3490d81d53d24af849cc14fed8a8ec79..787735324c2b6692ad9654a16fcce863cf8aec1e 100644
--- a/src/Gargantext/Components/Nodes/Annuaire.purs
+++ b/src/Gargantext/Components/Nodes/Annuaire.purs
@@ -2,9 +2,10 @@ module Gargantext.Components.Nodes.Annuaire
  -- ( annuaire )
  where
 
-import Prelude (bind, const, identity, pure, show, ($), (<$>), (<>))
 import Data.Argonaut (class DecodeJson, decodeJson, (.:), (.:?))
 import Data.Array as A
+import Data.Generic.Rep (class Generic)
+import Data.Generic.Rep.Eq (genericEq)
 import Data.Maybe (Maybe(..), maybe, fromMaybe)
 import Data.Sequence as Seq
 import Data.Tuple (fst, snd)
@@ -240,7 +241,9 @@ contactCellsCpt = here.component "contactCells" cpt where
 data HyperdataAnnuaire = HyperdataAnnuaire
   { title :: Maybe String
   , desc  :: Maybe String }
-
+derive instance genericHyperdataAnnuaire :: Generic HyperdataAnnuaire _
+instance eqHyperdataAnnuaire :: Eq HyperdataAnnuaire where
+  eq = genericEq
 instance decodeHyperdataAnnuaire :: DecodeJson HyperdataAnnuaire where
   decodeJson json = do
     obj   <- decodeJson json
@@ -259,7 +262,9 @@ newtype AnnuaireInfo =
   , date      :: String
   , hyperdata :: HyperdataAnnuaire
   }
-
+derive instance genericAnnuaireInfo :: Generic AnnuaireInfo _
+instance eqAnnuaireInfo :: Eq AnnuaireInfo where
+  eq = genericEq
 instance decodeAnnuaireInfo :: DecodeJson AnnuaireInfo where
   decodeJson json = do
     obj <- decodeJson json
diff --git a/src/Gargantext/Components/Nodes/Annuaire/User/Contacts/Types.purs b/src/Gargantext/Components/Nodes/Annuaire/User/Contacts/Types.purs
index d33d3350511a3f9262cd6127839a557f71035572..c1573e5cbd050c1f6eabe2978106eae4ff6d1b7a 100644
--- a/src/Gargantext/Components/Nodes/Annuaire/User/Contacts/Types.purs
+++ b/src/Gargantext/Components/Nodes/Annuaire/User/Contacts/Types.purs
@@ -1,13 +1,17 @@
 module Gargantext.Components.Nodes.Annuaire.User.Contacts.Types where
 
-import Prelude (bind, pure, ($))
 import Data.Argonaut (class DecodeJson, class EncodeJson, decodeJson, (.:), (.:!), (.:?), (:=), (~>), jsonEmptyObject)
 import Data.Array as A
+import Data.Generic.Rep (class Generic)
+import Data.Generic.Rep.Eq (genericEq)
 import Data.Lens
 import Data.Maybe (Maybe(..), fromMaybe)
+import Data.Newtype (class Newtype)
 import Data.String as S
+
+import Gargantext.Prelude
+
 import Gargantext.Utils.DecodeMaybe ((.?|))
-import Data.Newtype (class Newtype)
 
 -- TODO: should it be a NodePoly HyperdataContact ?
 newtype NodeContact =
@@ -20,7 +24,9 @@ newtype NodeContact =
   , typename  :: Maybe Int
   , userId    :: Maybe Int
   }
-
+derive instance genericNodeContact :: Generic NodeContact _
+instance eqNodeContact :: Eq NodeContact where
+  eq = genericEq
 instance decodeNodeContact :: DecodeJson NodeContact where
   decodeJson json = do
     obj       <- decodeJson json
@@ -40,7 +46,6 @@ instance decodeNodeContact :: DecodeJson NodeContact where
                    , typename
                    , userId
                    }
-
 derive instance newtypeNodeContact :: Newtype NodeContact _
 
 ----------------------------------------------------------------------------
@@ -55,8 +60,9 @@ newtype Contact' =
   , typename :: Maybe Int
   , userId :: Maybe Int
   }
-
-
+derive instance genericContact' :: Generic Contact' _
+instance eqContact' :: Eq Contact' where
+  eq = genericEq
 instance decodeContact' :: DecodeJson Contact' where
   decodeJson json = do
     obj       <- decodeJson json
@@ -90,8 +96,9 @@ newtype Contact =
   , typename :: Maybe Int
   , userId :: Maybe Int
   }
-
-
+derive instance genericContact :: Generic Contact _
+instance eqContact :: Eq Contact where
+  eq = genericEq
 instance decodeContact :: DecodeJson Contact where
   decodeJson json = do
     obj       <- decodeJson json
@@ -156,7 +163,9 @@ newtype ContactWho =
   }
 
 derive instance newtypeContactWho :: Newtype ContactWho _
-
+derive instance genericContactWho :: Generic ContactWho _
+instance eqContactWho :: Eq ContactWho where
+  eq = genericEq
 instance decodeContactWho :: DecodeJson ContactWho
   where
     decodeJson json = do
@@ -171,7 +180,6 @@ instance decodeContactWho :: DecodeJson ContactWho
       let f = fromMaybe [] freetags
 
       pure $ ContactWho {idWho, firstName, lastName, keywords:k, freetags:f}
-
 instance encodeContactWho :: EncodeJson ContactWho
   where
     encodeJson (ContactWho cw) =
@@ -209,7 +217,9 @@ newtype ContactWhere =
   , exit         :: Maybe String }
 
 derive instance newtypeContactWhere :: Newtype ContactWhere _
-
+derive instance genericContactWhere :: Generic ContactWhere _
+instance eqContactWhere :: Eq ContactWhere where
+  eq = genericEq
 instance decodeContactWhere :: DecodeJson ContactWhere
   where
     decodeJson json = do
@@ -228,7 +238,6 @@ instance decodeContactWhere :: DecodeJson ContactWhere
       let l = fromMaybe [] labTeamDepts
 
       pure $ ContactWhere {organization:o, labTeamDepts:l, role, office, country, city, touch, entry, exit}
-
 instance encodeContactWhere :: EncodeJson ContactWhere
   where
     encodeJson (ContactWhere cw) =
@@ -264,7 +273,9 @@ newtype ContactTouch =
   , url   :: Maybe String }
 
 derive instance newtypeContactTouch :: Newtype ContactTouch _
-
+derive instance genericContactTouch :: Generic ContactTouch _
+instance eqContactTouch :: Eq ContactTouch where
+  eq = genericEq
 instance decodeContactTouch :: DecodeJson ContactTouch
   where
     decodeJson json = do
@@ -273,7 +284,6 @@ instance decodeContactTouch :: DecodeJson ContactTouch
       phone <- obj .:? "phone"
       url   <- obj .:? "url"
       pure $ ContactTouch {mail, phone, url}
-
 instance encodeContactTouch :: EncodeJson ContactTouch
   where
     encodeJson (ContactTouch ct) =
@@ -302,7 +312,9 @@ newtype HyperdataContact =
                       , who            :: Maybe ContactWho
                       }
 derive instance newtypeHyperdataContact :: Newtype HyperdataContact _
-
+derive instance genericHyperdataContact :: Generic HyperdataContact _
+instance eqHyperdataContact :: Eq HyperdataContact where
+  eq = genericEq
 instance decodeHyperdataContact :: DecodeJson HyperdataContact
   where
     decodeJson json = do
@@ -319,7 +331,6 @@ instance decodeHyperdataContact :: DecodeJson HyperdataContact
       let ou' = fromMaybe [] ou
 
       pure $ HyperdataContact {bdd, who, ou:ou', title, source, lastValidation, uniqId, uniqIdBdd}
-
 instance encodeHyperdataContact :: EncodeJson HyperdataContact
   where
     encodeJson (HyperdataContact {bdd, lastValidation, ou, source, title, uniqId, uniqIdBdd, who}) =
@@ -350,14 +361,15 @@ newtype HyperdataUser =
     shared :: Maybe HyperdataContact
   }
 derive instance newtypeHyperdataUser :: Newtype HyperdataUser _
-
+derive instance genericHyperdataUser :: Generic HyperdataUser _
+instance eqHyperdataUser :: Eq HyperdataUser where
+  eq = genericEq
 instance decodeHyperdataUser :: DecodeJson HyperdataUser
   where
     decodeJson json = do
       obj    <- decodeJson json
       shared <- obj .:? "shared"
       pure $ HyperdataUser { shared }
-
 instance encodeHyperdataUser :: EncodeJson HyperdataUser
   where
     encodeJson (HyperdataUser {shared}) =
diff --git a/src/Gargantext/Components/Nodes/Corpus/Chart/Common.purs b/src/Gargantext/Components/Nodes/Corpus/Chart/Common.purs
index b9c3ca614a0396d54efbc43f14d9bbe3bd03fbcb..27081c4ed1d55c4811455abfbaff9bc761dfc6f0 100644
--- a/src/Gargantext/Components/Nodes/Corpus/Chart/Common.purs
+++ b/src/Gargantext/Components/Nodes/Corpus/Chart/Common.purs
@@ -28,10 +28,10 @@ type MetricsLoadViewProps a = (
 cacheName :: String
 cacheName = "metrics"
 
-metricsLoadView :: forall a. Record (MetricsLoadViewProps a) -> R.Element
+metricsLoadView :: forall a. Eq a => Record (MetricsLoadViewProps a) -> R.Element
 metricsLoadView p = R.createElement metricsLoadViewCpt p []
 
-metricsLoadViewCpt :: forall a. R.Component (MetricsLoadViewProps a)
+metricsLoadViewCpt :: forall a. Eq a => R.Component (MetricsLoadViewProps a)
 metricsLoadViewCpt = here.component "metricsLoadView" cpt
   where
     cpt { getMetrics, loaded, path, reload, session } _ = do
diff --git a/src/Gargantext/Components/Nodes/Corpus/Document/Types.purs b/src/Gargantext/Components/Nodes/Corpus/Document/Types.purs
index 04dadd06b8d60b7eec424b40bbc48bc1dbac9bc0..7a01f13516ebe4847a18528610f73f8c45a246c9 100644
--- a/src/Gargantext/Components/Nodes/Corpus/Document/Types.purs
+++ b/src/Gargantext/Components/Nodes/Corpus/Document/Types.purs
@@ -2,6 +2,7 @@ module Gargantext.Components.Nodes.Corpus.Document.Types where
 
 import Data.Argonaut (class DecodeJson, decodeJson, (.:), (.:?))
 import Data.Generic.Rep (class Generic)
+import Data.Generic.Rep.Eq (genericEq)
 import Data.Generic.Rep.Show (genericShow)
 import Data.Maybe (Maybe(..))
 
@@ -167,6 +168,8 @@ derive instance genericDocument   :: Generic Document   _
 derive instance genericDocumentV3 :: Generic DocumentV3 _
 derive instance genericStatus     :: Generic Status     _
 
+instance eqDocument :: Eq Document where
+  eq = genericEq
 instance showDocument :: Show Document where
   show = genericShow
 
diff --git a/src/Gargantext/Components/Nodes/Corpus/Types.purs b/src/Gargantext/Components/Nodes/Corpus/Types.purs
index ed628c295dd5bd469718035a6924d6d0cec9a058..4c44ce4eb8470e31fa00d1721cf2117e83b67766 100644
--- a/src/Gargantext/Components/Nodes/Corpus/Types.purs
+++ b/src/Gargantext/Components/Nodes/Corpus/Types.purs
@@ -1,22 +1,26 @@
 module Gargantext.Components.Nodes.Corpus.Types where
 
 import Data.Argonaut (class DecodeJson, class EncodeJson, decodeJson, (.:), (:=), (~>), jsonEmptyObject)
+import Data.Generic.Rep (class Generic)
+import Data.Generic.Rep.Eq (genericEq)
 import Data.List as List
 import Data.Maybe (Maybe(..))
 
+import Gargantext.Prelude
+
 import Gargantext.Components.Node (NodePoly)
 import Gargantext.Components.Nodes.Types (FTField, Field(..), FieldType(..), isJSON)
-import Gargantext.Prelude (bind, pure, ($))
 
 newtype Hyperdata =
   Hyperdata { fields :: List.List FTField }
-
+derive instance genericHyperdata :: Generic Hyperdata _
+instance eqHyperdata :: Eq Hyperdata where
+  eq = genericEq
 instance decodeHyperdata :: DecodeJson Hyperdata where
   decodeJson json = do
     obj <- decodeJson json
     fields <- obj .: "fields"
     pure $ Hyperdata {fields}
-
 instance encodeHyperdata :: EncodeJson Hyperdata where
   encodeJson (Hyperdata {fields}) = do
        "fields"  := fields
diff --git a/src/Gargantext/Components/Nodes/Dashboard/Types.purs b/src/Gargantext/Components/Nodes/Dashboard/Types.purs
index 8864acb627d3ec8e1df08f4e32e61f943af5250e..f6ed168d60d88b5427b983abb5901c580f286a6b 100644
--- a/src/Gargantext/Components/Nodes/Dashboard/Types.purs
+++ b/src/Gargantext/Components/Nodes/Dashboard/Types.purs
@@ -1,6 +1,8 @@
 module Gargantext.Components.Nodes.Dashboard.Types where
 
 import Data.Argonaut (class DecodeJson, class EncodeJson, decodeJson, (.:), (.:?), (:=), (~>), jsonEmptyObject)
+import Data.Generic.Rep (class Generic)
+import Data.Generic.Rep.Eq (genericEq)
 import Data.List as List
 import Data.Maybe (Maybe(..))
 import Effect.Aff (Aff)
@@ -20,6 +22,9 @@ newtype Hyperdata =
   , fields :: List.List FTField
   , preferences :: Preferences
   }
+derive instance genericHyperdata :: Generic Hyperdata _
+instance eqHyperdata :: Eq Hyperdata where
+  eq = genericEq
 instance decodeHyperdata :: DecodeJson Hyperdata where
   decodeJson json = do
     obj <- decodeJson json
diff --git a/src/Gargantext/Components/Nodes/File.purs b/src/Gargantext/Components/Nodes/File.purs
index 222006d5148da240777ea6c09b29cd9df9be85cb..2d506cba62e55b78bb1313db8a9262878f358ab7 100644
--- a/src/Gargantext/Components/Nodes/File.purs
+++ b/src/Gargantext/Components/Nodes/File.purs
@@ -1,6 +1,8 @@
 module Gargantext.Components.Nodes.File where
 
 import Data.Argonaut (class DecodeJson, decodeJson, (.:))
+import Data.Generic.Rep (class Generic)
+import Data.Generic.Rep.Eq (genericEq)
 import Data.Maybe (Maybe(..))
 import Effect.Aff (Aff)
 import Reactix as R
@@ -23,7 +25,9 @@ newtype HyperdataFile =
   , name :: String
   , path :: String
   }
-
+derive instance genericHyperdataFile :: Generic HyperdataFile _
+instance eqHyperdataFile :: Eq HyperdataFile where
+  eq = genericEq
 instance decodeHyperdataFile :: DecodeJson HyperdataFile where
   decodeJson json = do
     obj  <- decodeJson json
@@ -39,7 +43,9 @@ newtype File =
   , hyperdata :: HyperdataFile
   , name      :: String
   }
-
+derive instance genericFile :: Generic File _
+instance eqFile :: Eq File where
+  eq = genericEq
 instance decodeFile :: DecodeJson File where
   decodeJson json = do
     obj       <- decodeJson json
diff --git a/src/Gargantext/Components/Nodes/Frame.purs b/src/Gargantext/Components/Nodes/Frame.purs
index 84625cf20da933f240ad12f6f463141225e1a60e..b8a3b69f1c8804e2bb4dbd426dd5b490da2d6aaa 100644
--- a/src/Gargantext/Components/Nodes/Frame.purs
+++ b/src/Gargantext/Components/Nodes/Frame.purs
@@ -3,6 +3,7 @@ module Gargantext.Components.Nodes.Frame where
 import Data.Argonaut as Argonaut
 import Data.Argonaut (decodeJson, (.:))
 import Data.Generic.Rep (class Generic)
+import Data.Generic.Rep.Eq (genericEq)
 import Data.Generic.Rep.Show (genericShow)
 --import Gargantext.Utils.Argonaut (genericSumDecodeJson, genericSumEncodeJson, genericEnumDecodeJson, genericEnumEncodeJson)
 import Data.Maybe (Maybe(..))
@@ -26,13 +27,11 @@ here = R2.here "Gargantext.Components.Nodes.Frame"
 
 data Hyperdata = Hyperdata { base :: String, frame_id :: String }
 
-derive instance eqHyperdata :: Eq Hyperdata
-
 derive instance genericHyperdata :: Generic Hyperdata _
-
+instance eqHyperdata :: Eq Hyperdata where
+  eq = genericEq
 instance showHyperdata :: Show Hyperdata where
   show = genericShow
-
 instance decodeJsonHyperdata :: Argonaut.DecodeJson Hyperdata where
 -- TODO
 --  decodeJson = genericSumDecodeJson
@@ -41,8 +40,6 @@ instance decodeJsonHyperdata :: Argonaut.DecodeJson Hyperdata where
     base     <- obj .: "base"
     frame_id <- obj .: "frame_id"
     pure $ Hyperdata {base, frame_id}
-
-
 instance encodeJsonHyperdata :: Argonaut.EncodeJson Hyperdata where
   encodeJson = genericSumEncodeJson
 
diff --git a/src/Gargantext/Components/Search.purs b/src/Gargantext/Components/Search.purs
index bc2603a3e9ffdeabc27550354c7002bf6ea2db92..518e6b1b7bc5e563e1ca738d100901b22f720a29 100644
--- a/src/Gargantext/Components/Search.purs
+++ b/src/Gargantext/Components/Search.purs
@@ -3,6 +3,7 @@ module Gargantext.Components.Search where
 import Gargantext.Prelude (class Eq, class Show)
 import Data.Argonaut as Argonaut
 import Data.Generic.Rep (class Generic)
+import Data.Generic.Rep.Eq (genericEq)
 import Data.Generic.Rep.Show (genericShow)
 import Data.Maybe (Maybe)
 
@@ -74,9 +75,9 @@ data Document =
            , category   :: Int
            , score      :: Int
            }
-
-derive instance eqDocument :: Eq Document
 derive instance genericDocument :: Generic Document _
+instance eqDocument :: Eq Document where
+  eq = genericEq
 instance showDocument :: Show Document where
   show = genericShow
 instance decodeJsonDocument :: Argonaut.DecodeJson Document where
diff --git a/src/Gargantext/Hooks/Loader.purs b/src/Gargantext/Hooks/Loader.purs
index 06ea3608b198c100782a98f21448a590ad426c8f..f2b7129a10b1d9ab637d3d0119dfff39e230a3bc 100644
--- a/src/Gargantext/Hooks/Loader.purs
+++ b/src/Gargantext/Hooks/Loader.purs
@@ -16,6 +16,9 @@ import Gargantext.Utils.Crypto (Hash)
 import Gargantext.Utils.CacheAPI as GUC
 import Gargantext.Utils.Reactix as R2
 
+here :: R2.Here
+here = R2.here "Gargantext.Hooks.Loader"
+
 cacheName :: String
 cacheName = "cache-api-loader"
 
@@ -23,22 +26,43 @@ clearCache :: Unit -> Aff Unit
 clearCache _ = GUC.delete $ GUC.CacheName cacheName
 
 
-useLoader :: forall path st. Eq path
+useLoader :: forall path st. Eq path => Eq st
           => path
           -> (path -> Aff st)
           -> (st -> R.Element)
           -> R.Hooks R.Element
-useLoader path loader render = do
-  state <- R.useState' Nothing
-  useLoaderEffect path state loader
-  pure $ maybe (loadingSpinner {}) render (fst state)
+useLoader path loader' render = do
+  state <- T.useBox Nothing
+
+  useLoaderEffect path state loader'
+
+  pure $ loader { path, render, state } []
+
+
+type LoaderProps path st =
+  ( path   :: path
+  , render :: st -> R.Element
+  , state  :: T.Box (Maybe st) )
 
-useLoaderEffect :: forall st path. Eq path =>
+loader :: forall path st. Eq path => Eq st => R2.Component (LoaderProps path st)
+loader = R.createElement loaderCpt
+
+loaderCpt :: forall path st. Eq path => Eq st => R.Component (LoaderProps path st)
+loaderCpt = here.component "loader" cpt
+  where
+    cpt { path, render, state } _ = do
+      state' <- T.useLive T.unequal state
+
+      pure $ maybe (loadingSpinner {}) render state'
+
+
+useLoaderEffect :: forall st path. Eq path => Eq st =>
                       path
-                   -> R.State (Maybe st)
+                   -> T.Box (Maybe st)
                    -> (path -> Aff st)
                    -> R.Hooks Unit
-useLoaderEffect path state@(state' /\ setState) loader = do
+useLoaderEffect path state loader = do
+  state' <- T.useLive T.unequal state
   oPath <- R.useRef path
 
   R.useEffect' $ do
@@ -49,7 +73,7 @@ useLoaderEffect path state@(state' /\ setState) loader = do
       R.setRef oPath path
       R2.affEffect "G.H.Loader.useLoaderEffect" $ do
         l <- loader path
-        liftEffect $ setState $ const $ Just l
+        liftEffect $ T.write_ (Just l) state
 
 
 newtype HashedResponse a = HashedResponse { hash  :: Hash, value :: a }